⭕接口7:头插(LTPushFront)
🥰请看代码与注释👇
//头插 void LTPushFront(LTNode* phead, ListNodeDataType x) { assert(phead); LTNode* newnode = BuyLTNode(x); LTNode* first = phead->next; //记录哨兵卫头结点的下一节点 //构建各节点之间的关系 phead->next = newnode; newnode->prev = phead; newnode->next = first; first->prev = newnode; }
⭕接口8:尾插(LTPushBack)
🥰请看代码与注释👇
//尾插 void LTPushBack(LTNode* phead, ListNodeDataType x) { assert(phead); LTNode* tail = phead->prev; //找到尾节点 LTNode* newnode = BuyLTNode(x); //构建尾节点与新节点,新节点与哨兵卫头结点的关系 tail->next = newnode; newnode->prev = tail; newnode->next = phead; phead->prev = newnode; }
⭕接口9:头删(LTPopFront)
🥰请看代码与注释👇
//头删 void LTPopFront(LTNode* phead) { assert(!LTEmpty(phead)); LTNode* first = phead->next; //记录哨兵卫头节点下一节点及其的下一节点 LTNode* second = first->next; phead->next = second; second->prev = phead; free(first); }
⭕接口10:尾删(LTPopBack)
🥰请看代码与注释👇
//尾删 void LTPopBack(LTNode* phead) { //判空 以及 判断只剩哨兵卫头结点的情况 assert(!LTEmpty(phead)); //记录尾节点及其前一节点 LTNode* tail = phead->prev; LTNode* tailPrev = tail->prev; //构建尾节点前一节点与哨兵卫头结点的关系 tailPrev->next = phead; phead->prev = tailPrev; free(tail); //释放尾节点 }
⭕接口11:查找(LTFind)
🥰请看代码与注释👇
LTNode* LTFind(LTNode* phead, ListNodeDataType x) { assert(phead); LTNode* cur = phead->next;; while (cur != phead) { if (cur->data == x) //比较数据 { return cur; } cur = cur->next; //找到下一个节点 } return NULL; //没找到则返回NULL }
⭕接口12:修改(LTModify)
🥰请看代码与注释👇
//修改 void LTModify(LTNode* phead, LTNode* pos, ListNodeDataType x) { assert(phead); assert(pos); pos->data = x; }
⭕接口13:在pos之前插入(LTInsert)
🥰请看代码与注释👇
//在pos之前插入 void LTInsert(LTNode* pos, ListNodeDataType x) { assert(pos); LTNode* prev = pos->prev; LTNode* newnode = BuyLTNode(x); prev->next = newnode; newnode->prev = prev; newnode->next = pos; pos->prev = newnode; }
⭕接口14:删除pos位置的值(LTErase)
🥰请看代码与注释👇
//删除pos位置的值 void LTErase(LTNode* pos) { assert(pos); //记录pos的前一节点和后一节点 LTNode* posPrev = pos->prev; LTNode* posNext = pos->next; posPrev->next = posNext; posNext->prev = posPrev; free(pos); //释放节点 }
🐸四、完整代码
🥝List.h
#pragma once #include<stdio.h> #include<stdlib.h> #include<assert.h> #include<stdbool.h> //自定义类型 typedef int ListNodeDataType; //创建双向链表 typedef struct ListNode { struct ListNode* prev; struct ListNode* next; ListNodeDataType data; }LTNode; //初始化(创建哨兵卫) LTNode* LTInit(); //打印 void LTPrint(LTNode* phead); //释放 void LTDestroy(LTNode* phead); //判空 bool LTEmpty(LTNode* phead); //头插 void LTPushFront(LTNode* phead, ListNodeDataType x); //尾插 void LTPushBack(LTNode* phead, ListNodeDataType x); //头删 void LTPopFront(LTNode* phead); //尾删 void LTPopBack(LTNode* phead); //查找 LTNode* LTFind(LTNode* phead, ListNodeDataType x); //修改 void LTModify(LTNode* phead, LTNode* pos, ListNodeDataType x); //在pos之前插入 void LTInsert(LTNode* pos, ListNodeDataType x); //删除pos位置的值 void LTErase(LTNode* pos);
🥝List.c
#include "List.h" //创建新节点 LTNode* BuyLTNode(ListNodeDataType x) { LTNode* newnode = (LTNode*)malloc(sizeof(LTNode)); if (newnode == NULL) { perror("malloc fail"); return; } newnode->data = x; newnode->prev = NULL; newnode->next = NULL; return newnode; } //初始化(创建哨兵卫) LTNode* LTInit() { LTNode* phead = BuyLTNode(-1); //哨兵卫不存储有效值 phead->prev = phead; phead->next = phead; return phead; } //打印 void LTPrint(LTNode* phead) { assert(phead); printf("guard<==>"); LTNode* cur = phead->next; while (cur != phead) { printf("%d<==>", cur->data); cur = cur->next; } printf("\n"); } //释放 void LTDestroy(LTNode* phead) { assert(phead); LTNode* cur = phead->next; while (cur != phead) { LTNode* next = cur->next; free(cur); cur = next; } free(phead); } //判空 bool LTEmpty(LTNode* phead) { assert(phead); return phead->next == phead; } //头插 void LTPushFront(LTNode* phead, ListNodeDataType x) { assert(phead); LTNode* newnode = BuyLTNode(x); LTNode* first = phead->next; phead->next = newnode; newnode->prev = phead; newnode->next = first; first->prev = newnode; } 头插 //void LTPushFront(LTNode* phead, ListNodeDataType x) //{ // assert(phead); // // LTInsert(phead->next, x); //} //尾插 void LTPushBack(LTNode* phead, ListNodeDataType x) { assert(phead); LTNode* tail = phead->prev; LTNode* newnode = BuyLTNode(x); tail->next = newnode; newnode->prev = tail; newnode->next = phead; phead->prev = newnode; } 尾插 //void LTPushBack(LTNode* phead, ListNodeDataType x) //{ // assert(phead); // // LTInsert(phead, x); //} //头删 void LTPopFront(LTNode* phead) { assert(!LTEmpty(phead)); LTNode* first = phead->next; LTNode* second = first->next; phead->next = second; second->prev = phead; free(first); } 头删 //void LTPopFront(LTNode* phead) //{ // assert(!LTEmpty(phead)); // // LTEmpty(phead->next); //} //尾删 void LTPopBack(LTNode* phead) { assert(!LTEmpty(phead)); LTNode* tail = phead->prev; LTNode* tailPrev = tail->prev; tailPrev->next = phead; phead->prev = tailPrev; free(tail); } 尾删 //void LTPopBack(LTNode* phead) //{ // assert(!LTEmpty(phead)); // // LTEmpty(phead->prev); //} //查找 LTNode* LTFind(LTNode* phead, ListNodeDataType x) { assert(phead); LTNode* cur = phead->next;; while (cur != phead) { if (cur->data == x) { return cur; } cur = cur->next; } return NULL; } //修改 void LTModify(LTNode* phead, LTNode* pos, ListNodeDataType x) { assert(phead); assert(pos); pos->data = x; } //在pos之前插入 void LTInsert(LTNode* pos, ListNodeDataType x) { assert(pos); LTNode* prev = pos->prev; LTNode* newnode = BuyLTNode(x); prev->next = newnode; newnode->prev = prev; newnode->next = pos; pos->prev = newnode; } //删除pos位置的值 void LTErase(LTNode* pos) { assert(pos); LTNode* posPrev = pos->prev; LTNode* posNext = pos->next; posPrev->next = posNext; posNext->prev = posPrev; free(pos); }
🥝Test.c
#include "List.h" //头插测试 void TestList01() { LTNode* plist = LTInit(); LTPushFront(plist, 4); LTPushFront(plist, 3); LTPushFront(plist, 2); LTPushFront(plist, 1); LTPrint(plist); LTDestroy(plist); plist = NULL; } //尾插测试 void TestList02() { LTNode* plist = LTInit(); LTPushBack(plist, 4); LTPushBack(plist, 3); LTPushBack(plist, 2); LTPushBack(plist, 1); LTPrint(plist); LTDestroy(plist); plist = NULL; } //头删测试 void TestList03() { LTNode* plist = LTInit(); LTPushFront(plist, 4); LTPushFront(plist, 3); LTPushFront(plist, 2); LTPushFront(plist, 1); LTPopFront(plist); LTPrint(plist); LTDestroy(plist); plist = NULL; } //尾删测试 void TestList04() { LTNode* plist = LTInit(); LTPushFront(plist, 4); LTPushFront(plist, 3); LTPushFront(plist, 2); LTPushFront(plist, 1); LTPopBack(plist); LTPrint(plist); LTDestroy(plist); plist = NULL; } //查找修改测试 void TestList05() { LTNode* plist = LTInit(); LTPushFront(plist, 4); LTPushFront(plist, 3); LTPushFront(plist, 2); LTPushFront(plist, 1); LTNode* pos = LTFind(plist, 3); if (pos) { LTModify(plist, pos, 8); } LTPrint(plist); LTDestroy(plist); plist = NULL; } //在pos之前插入 void TestList06() { LTNode* plist = LTInit(); LTPushFront(plist, 4); LTPushFront(plist, 3); LTPushFront(plist, 2); LTPushFront(plist, 1); LTNode* pos = LTFind(plist, 3); if (pos) { LTInsert(pos, 7); } LTPrint(plist); LTDestroy(plist); plist = NULL; } //删除pos位置的值 void TestList07() { LTNode* plist = LTInit(); LTPushFront(plist, 4); LTPushFront(plist, 3); LTPushFront(plist, 2); LTPushFront(plist, 1); LTNode* pos = LTFind(plist, 2); if (pos) { LTErase(pos); } LTPrint(plist); LTDestroy(plist); plist = NULL; } int main() { //TestList01(); //TestList02(); //TestList03(); //TestList04(); //TestList05(); //TestList06(); //TestList07(); return 0; }
🥰这期内容比较容易一些而且比较有趣,希望烙铁们可以理解消化哦!
总结🥰
以上就是 【数据结构】带头双向循环链表—C语言版 的全部内容啦🥳🥳🥳🥳
本文章所在【数据结构与算法】专栏,感兴趣的烙铁可以订阅本专栏哦🥳🥳🥳
前途很远,也很暗,但是不要怕,不怕的人面前才有路。💕💕💕
小的会继续学习,继续努力带来更好的作品😊😊😊
创作写文不易,还多请各位大佬uu们多多支持哦🥰🥰🥰