当前位置: 首页 > news >正文

双向链表的实现

目录

一、双向链表的结构

二、双向链表的实现

2.1 双向链表的初始化LTInit

2.2 双向链表的打印LTPrint

2.3 双向链表的判空LTEmpty

2.4 尾插LTPushBack

2.5 尾删LTPopBack

2.6 头插LTPushFront

2.7 头删LTPopFront

2.8 查找LTFind

2.9 插入LTInsert

2.10 删除LTErase

2.11 销毁LTDestroy

三、顺序表和和链表的优缺点分析

四、代码

4.1 ListNode.h

4.2 ListNode.c

4.3 test.c


一、双向链表的结构

双向链表的结构如下图所示:

二、双向链表的实现

2.1 双向链表的初始化LTInit

实现代码如下:

LTNode* BuyNode(LTDataType x) {LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));if (newnode == NULL) {perror("BuyNode()::malloc");exit(1);}newnode->next = newnode;newnode->prev = newnode;newnode->data = x;return newnode;
}
LTNode* LTInit() {return BuyNode(0);
}

2.2 双向链表的打印LTPrint

实现代码如下:

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

2.3 双向链表的判空LTEmpty

实现代码如下:

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

2.4 尾插LTPushBack

实现代码如下:

LTNode* BuyNode(LTDataType x) {LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));if (newnode == NULL) {perror("BuyNode()::malloc");exit(1);}newnode->next = newnode;newnode->prev = newnode;newnode->data = x;return newnode;
}
void LTPushBack(LTNode* phead, LTDataType x) {assert(phead);LTNode* newnode = BuyNode(x);LTNode* tail = phead->prev;tail->next = newnode;newnode->prev = tail;newnode->next = phead;phead->prev = newnode;}

2.5 尾删LTPopBack

实现代码如下:

void LTPopBack(LTNode* phead)
{assert(phead);assert(LTEmpty(phead) != true);LTNode* tail = phead->prev;LTNode* pretail = tail->prev;pretail->next = phead;phead->prev = pretail;free(tail);
}

2.6 头插LTPushFront

实现代码如下:

LTNode* BuyNode(LTDataType x) {LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));if (newnode == NULL) {perror("BuyNode()::malloc");exit(1);}newnode->next = newnode;newnode->prev = newnode;newnode->data = x;return newnode;
}
void LTPushFront(LTNode* phead, LTDataType x) {assert(phead);LTNode* newnode = BuyNode(x);newnode->next = phead->next;newnode->prev = phead;phead->next = newnode;newnode->next->prev = newnode;
}

2.7 头删LTPopFront

实现代码如下:

void LTPopFront(LTNode* phead) {assert(phead);LTNode* del = phead->next;phead->next = del->next;del->next->prev = phead;free(del);
}

2.8 查找LTFind

实现代码如下:

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.9 插入LTInsert

实现代码如下:

void LTInsert(LTNode* pos, LTDataType x){assert(pos);LTNode* newnode = BuyNode(x);newnode->next = pos->next;newnode->prev = pos;pos->next = newnode;newnode->next->prev = newnode;}

2.10 删除LTErase

实现代码如下:

void LTErase(LTNode* pos) {assert(pos);LTNode* next = pos->next;LTNode* prev = pos->prev;next->prev = prev;prev->next = next;free(pos);
}

2.11 销毁LTDestroy

实现代码如下:

void LTDestroy(LTNode* phead) {assert(phead);LTNode* cur = phead->next;while (cur!=phead) {LTNode* next = cur->next;free(cur);cur = next;}phead->next = phead;phead->prev = phead;
}

三、顺序表和和链表的优缺点分析

不同点顺序表链表(单链表)
存储空间上物理上⼀定连续逻辑上连续,但物理上不⼀定连续
随机访问⽀持O(1)不⽀持:O(N)
任意位置插⼊或者删除元素可能需要搬移元素,效率低O(N)
只需修改指针指向
插⼊
动态顺序表,空间不够时需要扩容
没有容量的概念
应⽤场景元素⾼效存储+频繁访问任意位置插⼊和删除频繁

四、代码

4.1 ListNode.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
typedef int LTDataType;
typedef struct ListNode
{struct ListNode* prev;LTDataType data;struct ListNode* next;
}LTNode;//void LTInit(LTNode** pphead);
LTNode* LTInit();
void LTDestroy(LTNode* phead);
void LTPrint(LTNode* phead);
bool LTEmpty(LTNode* phead);void LTPushBack(LTNode* phead, LTDataType x);
void LTPopBack(LTNode* phead);void LTPushFront(LTNode* phead, LTDataType x);
void LTPopFront(LTNode* phead);
//在pos位置之后插入数据
void LTInsert(LTNode* pos, LTDataType x);
void LTErase(LTNode* pos);
LTNode* LTFind(LTNode* phead, LTDataType x);

4.2 ListNode.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"ListNode.h"
LTNode* BuyNode(LTDataType x) {LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));if (newnode == NULL) {perror("BuyNode()::malloc");exit(1);}newnode->next = newnode;newnode->prev = newnode;newnode->data = x;return newnode;
}
LTNode* LTInit() {return BuyNode(0);
}
void LTDestroy(LTNode* phead) {assert(phead);LTNode* cur = phead->next;while (cur!=phead) {LTNode* next = cur->next;free(cur);cur = next;}phead->next = phead;phead->prev = phead;
}
void LTPrint(LTNode* phead) {assert(phead);LTNode* cur = phead->next;while (cur != phead) {printf("%d->", cur->data);cur = cur->next;}printf("NULL\n");}
bool LTEmpty(LTNode* phead) {if (phead->next == phead) {return true;}else {return false;}
}void LTPushBack(LTNode* phead, LTDataType x) {assert(phead);LTNode* newnode = BuyNode(x);LTNode* tail = phead->prev;tail->next = newnode;newnode->prev = tail;newnode->next = phead;phead->prev = newnode;}
void LTPopBack(LTNode* phead)
{assert(phead);assert(LTEmpty(phead) != true);LTNode* tail = phead->prev;LTNode* pretail = tail->prev;pretail->next = phead;phead->prev = pretail;free(tail);
}void LTPushFront(LTNode* phead, LTDataType x) {assert(phead);LTNode* newnode = BuyNode(x);newnode->next = phead->next;newnode->prev = phead;phead->next = newnode;newnode->next->prev = newnode;
}
void LTPopFront(LTNode* phead) {assert(phead);LTNode* del = phead->next;phead->next = del->next;del->next->prev = phead;free(del);
}
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位置之后插入数据
void LTInsert(LTNode* pos, LTDataType x){assert(pos);LTNode* newnode = BuyNode(x);newnode->next = pos->next;newnode->prev = pos;pos->next = newnode;newnode->next->prev = newnode;}
void LTErase(LTNode* pos) {assert(pos);LTNode* next = pos->next;LTNode* prev = pos->prev;next->prev = prev;prev->next = next;free(pos);
}

4.3 test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"ListNode.h"
void test01()//测试尾插
{LTNode* phead = LTInit();LTPushBack(phead, 1);LTPushBack(phead, 2);LTPushBack(phead, 3);LTPushBack(phead, 4);LTPrint(phead);LTDestroy(phead);
}
void test02()//测试尾删
{LTNode* phead = LTInit();LTPushBack(phead, 1);LTPushBack(phead, 2);LTPushBack(phead, 3);LTPushBack(phead, 4);LTPrint(phead);//1 2 3 4LTPopBack(phead);LTPrint(phead);//1 2 3LTPopBack(phead);LTPrint(phead);//1 2LTPopBack(phead);LTPrint(phead);//1LTPopBack(phead);LTPrint(phead);//NULLLTDestroy(phead);}
void test03()//测试头插
{LTNode* phead = LTInit();LTPushFront(phead, 1);LTPushFront(phead, 2);LTPushFront(phead, 3);LTPushFront(phead, 4);LTPrint(phead);//4 3 2 1}
void test04()//测试头删
{LTNode* phead = LTInit();LTPushFront(phead, 1);LTPushFront(phead, 2);LTPushFront(phead, 3);LTPushFront(phead, 4);LTPrint(phead);//4 3 2 1LTPopFront(phead);LTPrint(phead);LTPopFront(phead);LTPrint(phead);LTPopFront(phead);LTPrint(phead);LTPopFront(phead);LTPrint(phead);
}
void tect05()//测试查找
{LTNode* phead = LTInit();LTPushFront(phead, 1);LTPushFront(phead, 2);LTPushFront(phead, 3);LTPushFront(phead, 4);LTNode* ret = LTFind(phead, 4);if (ret == NULL) {printf("找不到\n");}else {printf("找到了\n");}ret = LTFind(phead, 9);if (ret == NULL) {printf("找不到\n");}else {printf("找到了\n");}}
void test06()//测试插入
{LTNode* phead = LTInit();LTPushFront(phead, 1);LTPushFront(phead, 2);LTPushFront(phead, 3);LTPushFront(phead, 4);LTNode* ret = LTFind(phead, 4);LTInsert(ret, 99);LTPrint(phead);ret = LTFind(phead, 1);LTInsert(ret, 88);LTPrint(phead);ret = LTFind(phead, 3);LTInsert(ret, 77);LTPrint(phead);}
void test07()//测试删除
{LTNode* phead = LTInit();LTPushFront(phead, 1);LTPushFront(phead, 2);LTPushFront(phead, 3);LTPushFront(phead, 4);LTNode* ret = LTFind(phead, 4);LTErase(ret);LTPrint(phead);ret = LTFind(phead, 3);LTErase(ret);LTPrint(phead);ret = LTFind(phead, 2);LTErase(ret);LTPrint(phead);ret = LTFind(phead, 1);LTErase(ret);LTPrint(phead);}
int main() {//test01();//测试尾插//test02();//测试尾删//test03();//测试头插//test04();//测试头删//tect05();//测试查找、//test06();//测试插入//test07();//测试删除return 0;
}

http://www.dtcms.com/a/265841.html

相关文章:

  • [创业之路-468]:企业经营层 - 使用“市场-需求-竞争”三维模型筛选细分市场(市场维度、客户需求维度、竞争维度)
  • JavaEE-Linux环境部署
  • Java 核心技术与框架实战十八问
  • 专题:2025即时零售与各类人群消费行为洞察报告|附400+份报告PDF、原数据表汇总下载
  • 模拟IC设计提高系列6-Library导入与新建Library
  • 微信小程序41~50
  • 区块链(私有链搭建和实现)
  • 【C++】访问者模式
  • PHP语法基础篇(八):超全局变量
  • 鸿蒙应用开发:从网络获取数据
  • UE5中的AnimNotify
  • KDD 2025 | 地理定位中的群体智能:一个多智能体大型视觉语言模型协同框架
  • rabbitmq 与 Erlang 的版本对照表 win10 安装方法
  • SPLADE 在稀疏向量搜索中的原理与应用详解
  • MCP 传输机制(Streamable HTTP)
  • 多线程知识
  • 21、MQ常见问题梳理
  • 映射阿里云OSS(对象存储服务)
  • [创业之路-467]:企业经营层 - 《营销管理》的主要内容、核心思想以及对创业者的启示
  • 【Spring boot】tomcat Jetty Undertow对比,以及应用场景
  • Qt 事件
  • 医科+AI!和鲸支持南京医科大学医学数据挖掘课程实践教学落地
  • CCLinkIE转EtherCAT:食品产线测厚仪的“精准心跳”如何跳动?
  • 重学React(二):添加交互
  • 运维服务部中级服务工程师面试试题
  • 【Spring篇09】:制作自己的spring-boot-starter依赖1
  • 服务器如何配置防火墙规则开放/关闭端口?
  • ROS2---话题重映射
  • 能生成二维码的浏览器插件来了
  • 模型训练复习