目录
1.带头双向循环链表
2.链表实现
2.1可完成带头双向可循环链表节点的结构体
2.2申请一个可双向循环的节点
2.3初始化链表
2.4尾插
2.5尾删
2.6头插
2.7头删
2.8打印
2.9查找(修改)
2.10在pos之前插入x
2.11删除pos位置
2.12判空
2.13记录链表大小
2.14销毁
3.完整的带头双向循环链表代码
3.1——List.h
3.2——List.c
对比:
我们实际中最常用还是两种链表结构: 1.无头单向非循环链表![]()
用处:
结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构, 如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。 2.带头双向循环链表![]()
用处:
结构在链表中最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,反而使得实现功能更简单了。
typedef int LTDataType;
typedef struct ListNode
{struct ListNode* next;struct ListNode* prev;LTDataType data;
}LTNode;
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;
}
LTNode* ListInit()
{LTNode* phead = BuyListNode(-1);phead->next = phead;phead->prev = phead;return phead;
}
void LTPushBack(LTNode* phead, LTDataType x)
{assert(phead);//方法1/*LTNode* newnode = BuyListNode(x);LTNode* tail = phead->prev;tail->next = newnode;newnode->prev = tail;newnode->next = phead;phead->prev = newnode;*///方法2LTInsert(phead, x);
}
void LTPopBack(LTNode* phead)
{assert(phead);assert(phead->next != phead); // 空//方法1//LTNode* tail = phead->prev;//LTNode* tailPrev = tail->prev;//tailPrev->next = phead;//phead->prev = tailPrev;//free(tail);//方法2LTErase(phead->prev);
}
void LTPushFront(LTNode* phead, LTDataType x)
{assert(phead);//方法1(有关顺序)/*LTNode* newnode = BuyListNode(x);newnode->next = phead->next;phead->next->prev = newnode;phead->next = newnode;newnode->prev = phead;*///方法2(无关顺序)//LTNode* newnode = BuyListNode(x);//LTNode* first = phead->next;phead newnode first 顺序无关//phead->next = newnode;//newnode->prev = phead;//newnode->next = first;//first->prev = newnode;//方法3LTInsert(phead->next, x);}
void LTPopFront(LTNode* phead)
{assert(phead);assert(phead->next != phead); // 空//方法1/*LTNode* first = phead->next;LTNode* second = first->next;free(first);phead->next = second;second->prev = phead;*///方法2LTErase(phead->next);
}
void LTPrint(LTNode* phead)
{assert(phead);LTNode* cur = phead->next;while (cur != phead){printf("%d ", cur->data);cur = cur->next;}printf("\n");
}
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 newnode posprev->next = newnode;newnode->prev = prev;newnode->next = pos;pos->prev = newnode;
}
// 删除pos位置
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;
}
#pragma once#include
#include
#include
#include //typedef char LTDataType;
//typedef double LTDataType;
typedef int LTDataType;typedef struct ListNode
{struct ListNode* next;struct ListNode* prev;LTDataType data;
}LTNode;//创建节点
LTNode* BuyListNode(LTDataType x);
//初始化
LTNode* LTInit();//打印
void LTPrint(LTNode* phead);
//尾插尾删
void LTPushBack(LTNode* phead, LTDataType x);
void LTPopBack(LTNode* phead);
//头插头删
void LTPushFront(LTNode* phead, LTDataType x);
void LTPopFront(LTNode* phead);
//查找
LTNode* LTFind(LTNode* phead, LTDataType x);// pos前面插入
void LTInsert(LTNode* pos, LTDataType x);
// pos位置删除
void LTErase(LTNode* pos);
//判空
bool LTEmpty(LTNode* phead);
//大小
size_t LTSize(LTNode* phead);
//销毁
void LTDestroy(LTNode* phead);
#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;
}LTNode* LTInit()
{LTNode* phead = BuyListNode(-1);phead->next = phead;phead->prev = phead;return phead;
}void LTPrint(LTNode* phead)
{assert(phead);LTNode* cur = phead->next;while (cur != phead){printf("%d ", cur->data);cur = cur->next;}printf("\n");
}void LTPushBack(LTNode* phead, LTDataType x)
{assert(phead);//方法1/*LTNode* newnode = BuyListNode(x);LTNode* tail = phead->prev;tail->next = newnode;newnode->prev = tail;newnode->next = phead;phead->prev = newnode;*///方法2LTInsert(phead, x);
}void LTPopBack(LTNode* phead)
{assert(phead);assert(phead->next != phead); // 空//方法1//LTNode* tail = phead->prev;//LTNode* tailPrev = tail->prev;//tailPrev->next = phead;//phead->prev = tailPrev;//free(tail);//方法2LTErase(phead->prev);
}void LTPushFront(LTNode* phead, LTDataType x)
{assert(phead);//方法1(有关顺序)/*LTNode* newnode = BuyListNode(x);newnode->next = phead->next;phead->next->prev = newnode;phead->next = newnode;newnode->prev = phead;*///方法2(无关顺序)//LTNode* newnode = BuyListNode(x);//LTNode* first = phead->next;phead newnode first 顺序无关//phead->next = newnode;//newnode->prev = phead;//newnode->next = first;//first->prev = newnode;//方法3LTInsert(phead->next, x);}void LTPopFront(LTNode* phead)
{assert(phead);assert(phead->next != phead); // 空//方法1/*LTNode* first = phead->next;LTNode* second = first->next;free(first);phead->next = second;second->prev = phead;*///方法2LTErase(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 newnode posprev->next = newnode;newnode->prev = prev;newnode->next = pos;pos->prev = newnode;
}// 删除pos位置
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;
}