C语言双向循环链表如何实现,有什么优缺点
导读:这篇文章给大家分享的是“C语言双向循环链表如何实现,有什么优缺点”,文中的讲解内容简单清晰,对大家学习和理解有一定的参考价值和帮助,有这方面学习需要的朋友,接下来就跟随小编一起学习一下“C语言双向循环链表如何实现,有什么优缺点”吧。 本文...
这篇文章给大家分享的是“C语言双向循环链表如何实现,有什么优缺点”,文中的讲解内容简单清晰,对大家学习和理解有一定的参考价值和帮助,有这方面学习需要的朋友,接下来就跟随小编一起学习一下“C语言双向循环链表如何实现,有什么优缺点”吧。本文实例为大家分享了C语言实现带头双向循环链表的接口,供大家参考,具体内容如下
各函数功能如下
申请空间
ListNode* BuyListNode(LTDataType x) { ListNode* node = (ListNode*)malloc(sizeof(ListNode)); node-> next = NULL; node-> prev = NULL; node-> data = x; return node; }
初始化
ListNode* ListInit() { ListNode* phead = BuyListNode(0); phead-> next = phead; phead-> prev = phead; return phead; }
指定位置插入
void ListInsert(ListNode* pos, LTDataType x) { assert(pos); ListNode* prev = pos-> prev; ListNode* newnode = BuyListNode(x); prev-> next = newnode; newnode-> prev = prev; newnode-> next = pos; pos-> prev = newnode; }
头插
void ListPushFront(ListNode* phead, LTDataType x) { //assert(phead); //ListNode* first = phead-> next; //ListNode* newnode = BuyListNode(x); phead newnode first //phead-> next = newnode; //newnode-> prev = phead; //newnode-> next = first; //first-> prev = newnode; ListInsert(phead-> next, x); //实现了指定位置插入后,可以套用 }
尾插
void ListPushBack(ListNode* phead, LTDataType x) { //assert(phead); //ListNode* tail = phead-> prev; //ListNode* newnode = BuyListNode(x); //tail-> next = newnode; //newnode-> prev = tail; //newnode-> next = phead; //phead-> prev = newnode; ListInsert(phead, x); }
指定位置删除
void ListErase(ListNode* pos) { assert(pos); ListNode* prev = pos-> prev; ListNode* next = pos-> next; prev-> next = next; next-> prev = prev; free(pos); }
头删
void ListPopFront(ListNode* phead) { //assert(phead); //assert(phead-> next != phead); //ListNode* first = phead-> next; //ListNode* second = first-> next; //free(first); //phead-> next = second; //second-> prev = phead; ListErase(phead-> next); }
尾删
void ListPopBack(ListNode* phead) { //assert(phead); //assert(phead-> next != phead); //ListNode* tail = phead-> prev; //ListNode* tailPrev = tail-> prev; //free(tail); //tailPrev-> next = phead; //phead-> prev = tailPrev; ListErase(phead-> prev); }
查找
ListNode* ListFind(ListNode* phead, LTDataType x) { assert(phead); ListNode* cur = phead-> next; while (cur) { if (cur-> data == x) { return cur; } cur = cur-> next; } return NULL; }
判空
int ListEmpty(ListNode* phead) { assert(phead); return phead-> next == phead ? 1 : 0; }
元素个数
int ListSize(ListNode* phead) { assert(phead); int size = 0; ListNode* cur = phead-> next; while (cur != phead) { size++; cur = cur-> next; } return size; }
链表销毁
void ListDestory(ListNode* phead) { assert(phead); ListNode* cur = phead-> next; while (cur != phead) { ListNode* next = cur-> next; free(cur); cur = next; } free(phead); phead = NULL; }
List.h
#pragma once #define _CRT_SECURE_NO_WARNINGS 1 #include stdlib.h> #include stdio.h> #include assert.h> typedef int LTDataType; typedef struct ListNode { struct ListNode* next; struct ListNode* prev; LTDataType data; } ListNode; //打印 void ListPrint(ListNode* phead); //申请空间 ListNode* BuyListNode(LTDataType x); //初始化 ListNode* ListInit(); //尾插 void ListPushBack(ListNode* phead, LTDataType x); //头插 void ListPushFront(ListNode* phead, LTDataType x); //尾删 void ListPopBack(ListNode* phead); //头删 void ListPopFront(ListNode* phead); //查找 ListNode* ListFind(ListNode* phead, LTDataType x); //插入 void ListInsert(ListNode* pos, LTDataType x); //删除 void ListErase(ListNode* pos); //空返回1,非空返回0 int ListEmpty(ListNode* phead); //元素个数 int ListSize(ListNode* phead); //链表销毁 void ListDestory(ListNode* phead);
List.c
#include "List.h" ListNode* BuyListNode(LTDataType x) { ListNode* node = (ListNode*)malloc(sizeof(ListNode)); node-> next = NULL; node-> prev = NULL; node-> data = x; return node; } ListNode* ListInit() { ListNode* phead = BuyListNode(0); phead-> next = phead; phead-> prev = phead; return phead; } //打印 void ListPrint(ListNode* phead) { ListNode* cur = phead-> next; while (cur != phead) { printf("%d ", cur-> data); cur = cur-> next; } puts("\n------------------------------------------------\n"); } void ListPushBack(ListNode* phead, LTDataType x) { //assert(phead); //ListNode* tail = phead-> prev; //ListNode* newnode = BuyListNode(x); //tail-> next = newnode; //newnode-> prev = tail; //newnode-> next = phead; //phead-> prev = newnode; ListInsert(phead, x); } //头插 void ListPushFront(ListNode* phead, LTDataType x) { //assert(phead); //ListNode* first = phead-> next; //ListNode* newnode = BuyListNode(x); phead newnode first //phead-> next = newnode; //newnode-> prev = phead; //newnode-> next = first; //first-> prev = newnode; ListInsert(phead-> next, x); } //尾删 void ListPopBack(ListNode* phead) { //assert(phead); //assert(phead-> next != phead); //ListNode* tail = phead-> prev; //ListNode* tailPrev = tail-> prev; //free(tail); //tailPrev-> next = phead; //phead-> prev = tailPrev; ListErase(phead-> prev); } //头删 void ListPopFront(ListNode* phead) { //assert(phead); //assert(phead-> next != phead); //ListNode* first = phead-> next; //ListNode* second = first-> next; //free(first); //phead-> next = second; //second-> prev = phead; ListErase(phead-> next); } //查找 ListNode* ListFind(ListNode* phead, LTDataType x) { assert(phead); ListNode* cur = phead-> next; while (cur) { if (cur-> data == x) { return cur; } cur = cur-> next; } return NULL; } //插入 void ListInsert(ListNode* pos, LTDataType x) { assert(pos); ListNode* prev = pos-> prev; ListNode* newnode = BuyListNode(x); prev-> next = newnode; newnode-> prev = prev; newnode-> next = pos; pos-> prev = newnode; } //删除 void ListErase(ListNode* pos) { assert(pos); ListNode* prev = pos-> prev; ListNode* next = pos-> next; prev-> next = next; next-> prev = prev; free(pos); } //空返回1,非空返回0 int ListEmpty(ListNode* phead) { assert(phead); return phead-> next == phead ? 1 : 0; } int ListSize(ListNode* phead) { assert(phead); int size = 0; ListNode* cur = phead-> next; while (cur != phead) { size++; cur = cur-> next; } return size; } void ListDestory(ListNode* phead) { assert(phead); ListNode* cur = phead-> next; while (cur != phead) { ListNode* next = cur-> next; free(cur); cur = next; } free(phead); phead = NULL; }
test.c
#include "List.h" void TestList1() { ListNode* plist = ListInit(); ListPushBack(plist, 1); ListPushBack(plist, 2); ListPushBack(plist, 3); ListPushBack(plist, 4); ListPrint(plist); ListPushFront(plist, 0); ListPushFront(plist, -1); ListPushFront(plist, -2); ListPrint(plist); ListPopFront(plist); ListPopFront(plist); ListPopFront(plist); ListPrint(plist); ListDestory(plist); plist = NULL; } int main() { TestList1(); return 0; }
总结
链表优点:
1.按需申请内存,需要存一个数据,就申请一块内存。不存在空间浪费。
2.任意位置O(1)时间内插入删除数据
链表缺点:
1.不支持下标的随机访问
2.缓存命中率相对低。
顺序表优点
1.按下标去进行随机访问
2.cpu高速缓存命中率比较高
顺序表缺点
1.空间不够需要增容。(一定程序的性能消耗),可能存在一定的空间浪费
2.头部或者中间插入删除数据,需要挪动数据,效率比较低->
O(N)
以上就是关于“C语言双向循环链表如何实现,有什么优缺点”的相关知识,感谢各位的阅读,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注网络,小编每天都会为大家更新不同的知识。
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: C语言双向循环链表如何实现,有什么优缺点
本文地址: https://pptw.com/jishu/654873.html