双向链表定义如下:
typedef struct list
{
struct list *fwd;
struct list *bwd;
int data;
} list;
根节点root不带数据,root->fwd指向首节点,root->bwd指向尾节点,链表为空时,两者均为NULL。
普通节点中,fwd指向正向的后一个,bwd指向反向的前一个。
首节点的bwd为NULL,尾节点的fwd为NULL。
下面的例子中,数据不重复,升序排列。
插入:
插入在pCur和pNext之间,一般操作为:
1. pCur->fwd指向pNode
2. pNode->fwd指向pNext
3. pNext->bwd指向pNode
4. pNode->bwd指向pCur
1和2是通用操作,3和4需要根据首尾节点分别处理。
插入在尾节点之后,则步骤3不需要,但要更新root->bwd,使其指向新的尾节点pNode。
插入在首节点之前,则步骤4不需要,但要更新root->fwd,使其指向新的首节点pNode(由步骤1统一完成)。还要将新的首节点pNode->fwd置为NULL。
int insert_list(list *root, int data)
{
list *pCur, *pNext, *pNode;
for (pCur = root; (pNext = pCur->fwd) != NULL; pCur = pNext)
{
if (pNext->data > data)
{
break;
}
}
pNode = malloc(sizeof(list));
if (NULL == pNode)
{
return -1;
}
pNode->data = data;
pNode->fwd = pNext;
pCur->fwd = pNode;
if (pCur != root)
{
pNode->bwd = pCur;
}
else
{
pNode->bwd = NULL;
}
if (pNext != NULL)
{
pNext->bwd = pNode;
}
else
{
root->bwd = pNode;
}
return 0;
}
删除:
删除pNext(若存在),一般操作为:
1. pCur->fwd指向pNext->fwd
2. pNext->fwd->bwd指向pNext->bwd(注意不能用pCur替换)
若是删除尾节点,则步骤2不需要,但要更新root->bwd,使其指向新的尾节点pNext->bwd。
int remove_list(list *root, int data)
{
list *pCur, *pNext;
for (pCur = root; (pNext = pCur->fwd) != NULL; pCur = pNext)
{
if (pNext->data == data)
{
break;
}
}
if (pNext)
{
pCur->fwd = pNext->fwd;
if (pNext->fwd != NULL)
{
pNext->fwd->bwd = pNext->bwd; // not pCur
}
else
{
root->bwd = pNext->bwd;
}
free(pNext);
}
return 0;
}
用法:
list list;
list.fwd = NULL;
list.bwd = NULL;
list.data = -1;
...
insert_list(&list, n);
...
remove_list(&list, n);