双向有头循环链表的结构体只是增加了一个前一个节点
typedef struct SListNode
{
DataType data;
struct SList* pPrev;
struct SList* pNext;
}SListNode;
当链表为空是,还是有一个节点 ,那就是头节点,此时:
当链表不为空时:
双向链表的初始化:
一定要注意,链表的初始化,相当于要初始化一个节点,使它的Next指向自己。它的Prev也指向自己。
SListNode* SListInit()//初始化,即使是一个空链表,也要创建一个节点,给malloc一份内存
{
DataType x=0;
SListNode* list = BuyNode(x);
list->pNext = list;
list->pPrev = list;
return list;
}
建立一个节点:
SListNode* BuyNode(DataType x)
{
SListNode* Node = (SListNode*)malloc(sizeof(SListNode));
assert(Node);
Node->data = x;
Node->pNext = NULL;
Node->pPrev = NULL;
return Node;
}
头插:
void SListPushFront(SListNode *ppHead, DataType x)//头插
{
while (ppHead == NULL)
{
return;
}
SListNode* NewNode = NULL;
SListNode* PHead_Next = (ppHead)->pNext;
NewNode = BuyNode(x);
assert(NewNode);
NewNode->pNext = (ppHead)->pNext;
PHead_Next->pPrev = NewNode;
NewNode->pPrev = ppHead;
(ppHead)->pNext = NewNode;
//SListNodeInsert(ppHead, x);
}
尾插:
void SListPushBack(SListNode *ppHead, DataType x)//尾插
{
if (ppHead == NULL)
{
return;
}
SListNode*NewNode = BuyNode(x);
SListNode*cur = ppHead;//头
SListNode*Node = ppHead->pPrev;//尾
NewNode->pPrev = Node;
Node->pNext = NewNode;
NewNode->pNext = cur;
(cur)->pPrev = NewNode;
//SListNodeInsert(ppHead->pPrev, x);
}
尾删:
void SListNodePopBack(SListNode *ppHead)//尾删
{
SListNode* TailNode = ppHead->pPrev;
SListNode* PrevNode = TailNode->pPrev;
ppHead->pPrev = PrevNode;
PrevNode->pNext = ppHead;
free(TailNode);
//SListNodeErase(ppHead->pPrev);
}
头删:
void SListNodePopFront(SListNode *ppHead)//头删
{
SListNode* DelNode = ppHead->pNext;
SListNode* NextNode = DelNode->pNext;
ppHead->pNext = NextNode;
NextNode->pPrev = ppHead;
free(DelNode);
//SListNodeErase(ppHead->pNext);
}
在任意位置插入:
void SListNodeInsert(SListNode *pos,DataType x)
{
SListNode* NewNode = BuyNode(x);
SListNode* PrevNode = pos->pPrev;
NewNode->pNext = pos;
pos->pPrev = NewNode;
NewNode->pPrev = PrevNode;
PrevNode->pNext = NewNode;
}
在任意位置删除:
void SListNodeErase(SListNode *pos)//删除指定位置
{
assert(pos);
SListNode* PrevNode = pos->pPrev;
SListNode* NextNode = pos->pNext;
PrevNode->pNext = NextNode;
NextNode->pPrev = PrevNode;
free(pos);
}
查找某个节点:
SListNode* Find(SListNode* ppHead,DataType x)
{
SListNode* cur = ppHead;
while (cur)
{
if (cur->data == x)
return cur;
cur = cur->pNext;
}
}
删除遇到的第一个某个特定的元素:
void SListNodeRemove(SListNode *ppHead, DataType x)//删除一个指定元素
{
SListNode* Node = ppHead;
SListNode* cur = NULL;
SListNode* PrevNode = NULL;
SListNode* NextNode = NULL;
while (Node != ppHead->pNext)
{
cur = Node->pNext;
if (cur->data == x)
{
PrevNode = cur->pPrev;
NextNode = cur->pNext;
PrevNode->pNext = NextNode;
NextNode->pPrev = PrevNode;
free(cur);
return;
}
else
{
Node = Node->pNext;
}
}
}
删除所有特定的元素:
void SListNodeRemoveAll(SListNode *ppHead, DataType x)//删除所有指定元素
{
SListNode* Node = ppHead->pNext;
SListNode* pNode = NULL;
SListNode* cur = NULL;
SListNode* PrevNode = NULL;
SListNode* NextNode = NULL;
while (Node != ppHead)
{
cur = Node->pNext;
if (cur->data==5)
{
pNode = cur;
PrevNode = pNode->pPrev;
NextNode = pNode->pNext;
PrevNode->pNext = NextNode;
NextNode->pPrev = PrevNode;
free(pNode);
}
else
{
Node = Node->pNext;
}
}
}
测试:
void test()
{
SListNode* S = SListInit();
printf("前插:\n");
SListPushFront(S, 2);
SListPushFront(S, 4);
SListPushFront(S, 7);
SListPushFront(S, 6);
SListPrint(S);
printf("后插:\n");
SListPushBack(S, 1);
SListPushBack(S, 5);
SListPushBack(S, 5);
SListPushBack(S, 7);
SListPushBack(S, 9);
SListPrint(S);
printf("前删:\n");
SListNodePopFront(S);
SListPrint(S);
printf("后删:\n");
SListNodePopBack(S);
SListPrint(S);
printf("删除遇到第一个元素7\n");
SListNodeRemove(S, 7);
SListPrint(S);
printf("删除指定元素5\n");
SListNodeRemoveAll(S, 5);
SListPrint(S);
}
运行结果: