最好的时光,是一个人坐在某处安安静静读书的时候。就像最美妙的孤独,是一个人坐在街边长凳不为任何人的等候。
目录
带头双向循环链表
带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都 是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带 来很多优势,实现反而简单了,后面我们代码实现了就知道了。
简单结构
完整代码展示:
首先,我将通讯录分成了三个部分:
1、text.c //主函数测试
2、List.h //结构体和函数的声明,以及头文件的引用
3、List.c //各种功能函数的实现
List.h:
#pragma once #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <stdbool.h> typedef int LTDataType; typedef struct ListNode { LTDataType data; struct ListNode* prev; struct ListNode* next; }LTNode; //创建结点 LTNode* BuyListNode(LTDataType x); //初始化 LTNode* LTInit(); //尾插 void LTPushBack(LTNode* phead, LTDataType x); //尾删 void LTPopBack(LTNode* phead); //头插 void LTPushFront(LTNode* phead, LTDataType x); //头删 void LTPopFront(LTNode* phead); //打印 void LTPrint(LTNode* phead); //在pos之前插入x void LTInsert(LTNode* pos, LTDataType x); //查找 LTNode* LTFind(LTNode* phead, LTDataType x); //删除pos位置 void LTErase(LTNode* pos); bool LTEmpty(LTNode* phead); size_t LTSize(LTNode* phead); void LTDestroy(LTNode* phead);
List.c:
#define _CRT_SECURE_NO_WARNINGS 1 #include "List.h" //创建结点 LTNode* BuyListNode(LTDataType x) { LTNode* node = (LTNode*)malloc(sizeof(LTNode)); if (node == NULL) { perror("malloc fail"); exit(-1); } node->data = x; node->next = NULL; node->prev = NULL; return node; } //打印链表 void LTPrint(LTNode* phead) { LTNode* cur = phead->next; while (cur != phead) { printf("%d ", cur->data); cur = cur->next; } printf("\n"); } //初始化 LTNode* LTInit() { LTNode* phead = BuyListNode(-1); phead->next =phead; phead->prev =phead; return phead; } //尾插 void LTPushBack(LTNode* phead, LTDataType x) { assert(phead); /*LTNode* newnode = BuyListNode(x); LTNode* tail = phead->prev; tail->next = newnode; newnode->prev = tail; newnode->next = phead; phead->prev = newnode;*/ LTInsert(phead, x); } //尾删 void LTPopBack(LTNode* phead) { assert(phead); assert(phead->next != phead); /*LTNode* tail = phead->prev; LTNode* tailPrev = tail->prev; tailPrev->next = phead; phead->prev = tailPrev; free(tail);*/ LTErase(phead->prev); } //头插 void LTPushFront(LTNode* phead, LTDataType x) { assert(phead); //顺序不可以变 /*LTNode* newnode = BuyListNode(x); newnode->next = phead->next; phead->next->prev = newnode; newnode->prev = phead; phead->next = newnode;*/ //顺序可以变 /*LTNode* newnode = BuyListNode(x); LTNode* first = phead->next; newnode->next = first; first->prev = newnode; newnode->prev = phead; phead->next = newnode;*/ LTInsert(phead->next,x); } //头删 void LTPopFront(LTNode* phead) { assert(phead); assert(phead->next != phead); /*LTNode* first = phead->next; LTNode* second = first->next; free(first); phead->next = second; second->prev = phead;*/ LTErase(phead->next); } LTNode* LTFind(LTNode* phead, LTDataType x) { assert(phead); LTNode* cur = phead->next; while (cur != phead) { if (cur->data == x) { return cur; } cur = cur->next; } return NULL; } //在pos之前插入x void LTInsert(LTNode* pos, LTDataType x) { assert(pos); LTNode* prev = pos->prev; LTNode* newnode = BuyListNode(x); prev->next = newnode; newnode->prev = prev; newnode->next = pos; pos->prev = newnode; } void LTErase(LTNode* pos) { assert(pos); LTNode* prev = pos->prev; LTNode* next = pos->next; free(pos); prev->next = next; next->prev = prev; } bool LTEmpty(LTNode* phead) { assert(phead); /*if (phead->next == phead) { return true; } else { return false; }*/ return phead->next == phead; } size_t LTSize(LTNode* phead) { assert(phead); size_t size = 0; LTNode* cur = phead->next; while (cur != phead) { ++size; cur = cur->next; } return size; } void LTDestroy(LTNode* phead) { assert(phead); LTNode* cur = phead->next; while (cur != phead) { LTNode* next = cur->next; free(cur); cur = next; } free(phead); //phead = NULL; }
text.c:
#define _CRT_SECURE_NO_WARNINGS 1 #include "List.h" void TestList1() { LTNode* phead = LTInit(); LTPushBack(phead, 1); LTPushBack(phead, 2); LTPushBack(phead, 3); LTPushBack(phead, 4); LTPushBack(phead, 5); LTPrint(phead); LTPopBack(phead); LTPrint(phead); LTPushFront(phead, 100); LTPrint(phead); LTPopFront(phead); LTPrint(phead); } void TestList2() { LTNode* phead = LTInit(); LTPushBack(phead, 1); LTPushBack(phead, 2); LTPushBack(phead, 3); LTPushBack(phead, 4); LTPushBack(phead, 5); LTPrint(phead); LTPopFront(phead); LTPrint(phead); } void TestList3() { LTNode* phead = LTInit(); LTPushFront(phead, 1); LTPushFront(phead, 3); LTPushFront(phead, 5); LTPushFront(phead, 7); LTPushFront(phead, 9); LTPrint(phead); LTNode* pos = LTFind(phead, 3); if (pos) { LTInsert(pos, 100); } LTPrint(phead); LTErase(pos); LTPrint(phead); } void TestList4() { LTNode* phead = LTInit(); LTPushBack(phead, 1); LTPushBack(phead, 2); LTPushBack(phead, 3); LTPushBack(phead, 4); LTPrint(phead); LTPushFront(phead, 7); LTPushFront(phead, 8); LTPushFront(phead, 9); LTPushFront(phead, 10); LTPushFront(phead, 11); LTPrint(phead); } void TestList5() { LTNode* phead = LTInit(); LTPushFront(phead, 1); LTPushFront(phead, 2); LTPushFront(phead, 3); LTPushFront(phead, 4); LTPushFront(phead, 5); LTPrint(phead); LTNode* pos = LTFind(phead, 3); if (pos) { pos->data *= 10; } LTPrint(phead); LTDestroy(phead); phead = NULL; } int main() { TestList5(); return 0; }