目录
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;*/
//方法2
LTInsert(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);
//方法2
LTErase(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;
//方法3
LTInsert(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;*/
//方法2
LTErase(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 pos
prev->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;*/
//方法2
LTInsert(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);
//方法2
LTErase(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;
//方法3
LTInsert(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;*/
//方法2
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 newnode pos
prev->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;
}