date = x;cur->nex。【数据结构】动图详解双向链表( 四 )。" />

【数据结构】动图详解双向链表( 四 )


//SList.c文件 , 用于定义接口函数#define _CRT_SECURE_NO_WARNINGS 1#include "List.h"ListNode* CreatNode(ListDateType x){ListNode* cur=(ListNode*)malloc(sizeof(ListNode));cur->date = x;cur->next = NULL;cur->prev = NULL;return cur;}ListNode* InitList(){ListNode* phead = CreatNode(0); //创建头结点phead->next = phead; //前驱指针指向自身phead->prev = phead; //后继指针指向自身return phead; //将这个结点返回}void ListPushBack(ListNode* phead, ListDateType x){assert(phead != NULL);ListNode* NewNode = CreatNode(x);ListNode* tail = phead->prev; //找到链表尾tail->next = NewNode; NewNode->prev = tail;NewNode->next = phead;phead->prev = NewNode;}void ListPushFront(ListNode* phead, ListDateType x) //不改变头指针 , 无需传址{assert(phead != NULL); //保证链表有头结点 , 即完成了初始化ListNode* NewNode = CreatNode(x); //创建新结点ListNode* frist = phead->next; //找到链表头//进行头插phead->next = NewNode;NewNode->prev = phead;NewNode->next = frist;frist->prev = NewNode;}void ListPopBack(ListNode* phead){assert(phead != NULL);if (phead->next == NULL){return; //链表为空直接返回}ListNode* tail = phead->prev; //找到链表尾ListNode* prev = tail->prev;//找到前驱phead->prev = prev;prev->next = phead;free(tail);tail = NULL;}void ListPopFront(ListNode* phead){assert(phead != NULL); //确保链表初始化if (phead->next == NULL){return; //链表为空直接返回}ListNode* frist = phead->next; //找到链表头ListNode* second = frist->next; //找到链表头下一个结点//进行头删phead->next = second;second->prev = phead;free(frist); //释放结点frist = NULL;}ListNode* ListFind(ListNode* phead, ListDateType x){assert(phead != NULL); //确保已经初始化ListNode* cur = phead->next; //指向第一个有效结点 , 准备遍历while (cur != phead) //遍历一圈{if (cur->date == x){return cur; //找到了 , 返回结点}cur = cur->next; //指向下一结点}//找不到 , 返回空指针return NULL;}void ListErase(ListNode* phead, ListNode* pos){assert(pos != NULL); //确保已经初始化ListNode* next = pos->next; //后一个结点ListNode* prev = pos->prev; //前一个结点//进行删除prev->next = next;next->prev = prev;free(pos); //释放空间pos = NULL;}void ListInsert(ListNode* phead, ListNode* pos, ListDateType x){assert(pos != NULL); //确保已经初始化ListNode* NewNode = CreatNode(x); //创建新结点ListNode* prev = pos->prev; //前一个结点//进行插入NewNode->next = pos;pos->prev = NewNode;prev->next = NewNode;NewNode->prev = prev;}void ListPrint(ListNode* phead){assert(phead != NULL); //确保链表已经初始化ListNode* cur = phead->next; //指向有效部分while (cur != phead) //遍历一圈{printf("%d ", cur->date); //打印数据cur = cur->next; //指向下一结点}printf("\n");}void ListDestroy(ListNode* phead){assert(phead != NULL); //确保已经初始化ListNode* cur = phead->next; //指向有效部分while (cur != phead) //释放有效结点{ListNode* next = cur->next;free(cur);cur = next;}//释放头结点free(phead);phead = NULL;}
最后 ,  我们在text.c文件调用双向循环链表各个接口进行测试 , 如下:
//text.c文件 , 用于测试#define _CRT_SECURE_NO_WARNINGS 1#include "List.h"void ListText(){ListNode* plist = NULL;//初始化plist = InitList();printf("链表起始数据:\n");ListPrint(plist);//尾插ListPushBack(plist, 1);ListPushBack(plist, 2);ListPushBack(plist, 3);printf("尾插后数据:\n");ListPrint(plist);//头插ListPushFront(plist, 4);ListPushFront(plist,5);ListPushFront(plist, 6);printf("头插后数据:\n");ListPrint(plist);//尾删ListPopBack(plist);printf("尾删后数据:\n");ListPrint(plist);//头删ListPopFront(plist);printf("头删后数据:\n");ListPrint(plist);//修改数据为5的结点为50ListNode* cur1 = ListFind(plist, 5); //找数据为5结点if (cur1){cur1->date = 50; //查找附带着修改的作用}printf("修改数据为5的结点为50后\n");ListPrint(plist);//在date为4的结点前插入数据为7的结点ListNode* cur2 = ListFind(plist,4); //找数据为4结点if (cur2) {ListInsert(plist, cur2, 7); //插入}printf("在4前插入7后数据:\n");ListPrint(plist);//删除数据为1的结点ListNode* cur3 = ListFind(plist, 1); //找数据为1结点if (cur3) {ListErase(plist, cur3); //删除}printf("删除1后数据:\n");ListPrint(plist);//销毁ListDestroy(plist);}int main(){ListText();return 0;}