Would some of you experienced programmers please comment on my double linked lists code? Many thanks!
(Special thanks to Dave_Sinkula for getting me past a mental block!)
I am expecially concerned about possible "gotcha's", things I have not taken into consideration.
Code:
#include <stdio.h>
typedef struct node NODE;
struct node {
NODE *pNext;
NODE *pPrev;
char *pLine;
};
NODE *head;
NODE *tail;
int initList(); // init with NULL head/tail
void insertAtBeginning(NODE *);
void insertAtEnd(NODE *);
void insertBefore(NODE *, NODE *);
void insertAfter(NODE *, NODE *);
void removeNode(NODE *);
void traverseForward(NODE *);
void traverseBackward(NODE *);
void doSomething(NODE *pNode);
NODE * getNode();
int main(int argc, char *argv[]) {
char buf1[] = "this is buf 1.";
char buf2[] = "this is buf 2.";
char buf3[] = "this is buf 3.";
NODE *ppp;
if ( initList() == 0 )
printf("initList malloc failed.\n");
ppp = getNode(); // for simplicity here, error checking is done in getNode()
ppp->pLine = buf1;
insertAtEnd(ppp); // 1
ppp = getNode();
ppp->pLine = buf2;
insertAtBeginning(ppp); // 2 1
NODE *ppp2 = getNode();
ppp2->pLine = buf3;
insertAfter(ppp, ppp2); // 2 3 1
traverseForward(head); // print list
traverseBackward(tail);
removeNode(ppp2); // 2 1
free(ppp2);
traverseForward(head);
}
int initList() {
head = (NODE *) malloc(sizeof(NODE));
if (head == NULL)
return 0;
tail = (NODE *) malloc(sizeof(NODE));
if (tail == NULL)
return 0;
head->pNext = tail;
head->pPrev = NULL;
head->pLine = NULL;
tail->pNext = NULL;
tail->pPrev = head;
tail->pLine = NULL;
return 1;
}
void insertAtBeginning(NODE *pNewNode) {
insertAfter(head, pNewNode);
}
void insertAtEnd(NODE *pNewNode) {
insertBefore(tail, pNewNode);
}
void insertBefore(NODE *pNode, NODE *pNewNode) {
pNewNode->pPrev = pNode->pPrev;
pNewNode->pNext = pNode;
pNode->pPrev->pNext = pNewNode;
pNode->pPrev = pNewNode;
}
void insertAfter(NODE *pNode, NODE *pNewNode) {
pNewNode->pPrev = pNode;
pNewNode->pNext = pNode->pNext;
pNode->pNext->pPrev = pNewNode;
pNode->pNext = pNewNode;
}
void removeNode(NODE *pNode) {
pNode->pPrev->pNext = pNode->pNext;
pNode->pNext->pPrev = pNode->pPrev;
//free(pNode); // should be done by caller, if finished with this node
}
void traverseForward(NODE *pNode) {
NODE *ppp = pNode;
if (ppp == head)
ppp = head->pNext;
while (ppp != tail) {
doSomething(ppp); // do whatever... with this node
ppp = ppp->pNext;
}
}
void traverseBackward(NODE *pNode) {
NODE *ppp = pNode;
if (ppp == tail)
ppp = tail->pPrev;
while (ppp != head) {
doSomething(ppp); // do whatever... with this node
ppp = ppp->pPrev;
}
}
void doSomething(NODE *pNode) {
printf("%s\n",pNode->pLine);
}
NODE *getNode() {
NODE *ppp;
ppp = (NODE *) malloc(sizeof(NODE));
if ( ppp == NULL ) {
printf("malloc failed.\n");
exit(0);
}
return ppp;
}