【数据结构】——带头双向循环链表
创始人
2024-03-12 12:35:00
0

目录

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.带头双向循环链表

对比:

我们实际中最常用还是两种链表结构: 1.无头单向非循环链表

用处: 

结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构, 如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。 2.带头双向循环链表

 用处:

结构在链表中最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,反而使得实现功能更简单了。

2.链表实现

2.1可完成带头双向可循环链表节点的结构体

typedef int LTDataType;
typedef struct ListNode
{struct ListNode* next;struct ListNode* prev;LTDataType data;
}LTNode;

2.2申请一个可双向循环的节点

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;
}

2.3初始化链表

LTNode* ListInit()
{LTNode* phead = BuyListNode(-1);phead->next = phead;phead->prev = phead;return phead;
}

2.4尾插

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);
}

2.5尾删

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);
}

2.6头插

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);}

2.7头删

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);
}

2.8打印

void LTPrint(LTNode* phead)
{assert(phead);LTNode* cur = phead->next;while (cur != phead){printf("%d ", cur->data);cur = cur->next;}printf("\n");
}

2.9查找(修改)

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;
}

2.10在pos之前插入x

 

// 在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;
}

2.11删除pos位置

// 删除pos位置
void LTErase(LTNode* pos)
{assert(pos);LTNode* prev = pos->prev;LTNode* next = pos->next;free(pos);prev->next = next;next->prev = prev;
}

 2.12判空

bool LTEmpty(LTNode* phead)
{assert(phead);/*if (phead->next == phead){return true;}else{return false;}*/return phead->next == phead;
}

2.13记录链表大小

size_t LTSize(LTNode* phead)
{assert(phead);size_t size = 0;LTNode* cur = phead->next;while (cur != phead){++size;cur = cur->next;}return size;
}

2.14销毁

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;
}

3.完整的带头双向循环链表代码

3.1——List.h

#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);

3.2——List.c

#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;
}

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...