首页 > 其他分享 >数据结构-->带头双向循环链表--->优化

数据结构-->带头双向循环链表--->优化

时间:2023-03-21 18:00:55浏览次数:59  
标签:--- ListNode -- void next 链表 LTNode phead prev

好了,各位老铁!!现在开始本期讨论话题:<--头删数据----头插数据-->

直接上手代码:

头文件“List.h”

#include <stdio.h>
#inculde <stdlib.h> //扩容函数malloc库
#include <assert.h> //断言检验函数
#include <stdbool.h> //布尔函数

typedef int LTDataType;
typedef struct ListNode
{
struct ListNode* prev; //前指针
struct ListNode* next; //后指针
LTDataType data;
};

//初始化
ListNode* LTInitial();

//开辟空间
ListNode* LT_BUY(LTDataType x);

//打印
void LTPrint(LTNode* phead);

//布尔判断真假
bool boolEmpty(LTNode* phead);

//尾插数据
void LTPushBack(LTNode* phead, LTDataType x);

//尾删数据
void LTPopBack(LTNode* phead);

//头插数据
void LTPushFront(LTNode* phead, LTDataType x);

//头删数据
void LTPopFront(LTNode* phead);

-----> 代码实现环节“List.c”

#include "List.h"

//初始化
ListNode* LTInitial()
{
ListNode* phead = LT_BUY(-1); //设置哨兵位
phead ->next = phead;
phead ->prev = phead;
return phead;
}

//开辟空间
ListNode* LT_BUY(LTDataType x)
{
ListNode* newnode = (ListNode*) malloc(sizeof(ListNode));
if(newnode == NULL)
{
perror("malooc::fail");
return NULL;
}
newnode ->next = NULL;
newnode ->prev = NULL;
newnode ->data = x;
return newnode;
}

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

//布尔函数判断真假
//注意包含布尔头文件,别忘了
bool boolEmpty(LTNode* phead)
{
if(phead == NULL )
{
return true;
}
else
return false;
}

//尾插数据
void LTPushBack(LTNode* phead, LTDataType x)
{
assert(phead);
LTNode* newnode = LT_BUY(x);
LTNode* tail = phead ->prev;

tail ->next = newnode;
newnode ->prev = tail;
newnode ->next = phead;
phead ->prev = newnode;
}

//尾删数据
void LTPopBack(LTNode* phead)
{
assert(phead);
//还可以用布尔函数进行断言
assert(!boolEmpty(phead));

LTNode* tail = phead ->prev;
LTNode* tailprev = tail ->prev;

tailprev ->next = phead;
phead ->prev = tailprev;

free(tail);
tail = NULL;
}

/*--------------优化环节--------------*/
//头插数据
void LTPushFront(LTNode* phead, LTDataType x)
{
assert(phead); //必不可少的断言环节

LTInsert(phead ->next, x); //封装一个插入函数进行优化
}

//头删数据
void LTPopFront(LTNode* phead)
{
assert(phead);

LTErase(phead ->next); //封装一个删除函数进行优化
}

//指定位置pos的插入函数
void LTInsert(LTNode* pos, LTDataType x)
{
assert(phead);

LTNode* newnode = LT_BUY(x);
LTNode* prev = pos ->prev;

prev ->next = newnode;
newnode ->prev = prev;

newnode ->next = pos;
pos ->prev = newnode;
}

//指定位置pos的删除数据
void LTErase(LTNode* pos)
{
assert(phead);

LTNode* prev = pos ->prev;
LTNode* next = pos ->next;

prev >next = next;
next ->prev = prev;
free(pos);
}

补充头文件“List.h”

#include <stdio.h>
#inculde <stdlib.h> //扩容函数malloc库
#include <assert.h> //断言检验函数
#include <stdbool.h> //布尔函数

typedef int LTDataType;
typedef struct ListNode
{
struct ListNode* prev; //前指针
struct ListNode* next; //后指针
LTDataType data;
};

//初始化
ListNode* LTInitial();

//开辟空间
ListNode* LT_BUY(LTDataType x);

//打印
void LTPrint(LTNode* phead);

//布尔判断真假
bool boolEmpty(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);

//指定位置pos的删除数据
void LTErase(LTNode* pos);

现在进入测试环节“Test.c”

#include "List.h"

void test_01()
{
LTNode* plist = LTInitial();

LTPushFront(plist, 11);
LTPushFront(plist, 13);
LTPushFront(plist, 15);
LTPushFront(plist, 29);
LTPushFront(plist, 31);

LTPrint(plist);

LTPopFront(plist);
LTPopFront(plist);

LTPrint(plist);
}

int main()
{
test_01();
}

----->优化头删 头插的执行结果 :>

数据结构-->带头双向循环链表--->优化_数据结构

以上就是优化的过程,希望可以对各位老铁有所帮助!!

另外,部分代码的理解需要结合图示,如下 :>

数据结构-->带头双向循环链表--->优化_数据结构_02

此图可以方便理解,刚刚上述的头删 头插代码过程!!具以补充!!

本文末,链表算是告一段落了!!

其实,学会书写链表的代码,往往不足以展现自己对链表的实际理解情况!!

还需要进行检验以及运用到实际情况当中!!而OJ题的练习,则可以反映掌握的标准!!

那么接下来,就是有关链表OJ题的讲解过程了!!估计,又会有好几个专题再等着自己呢!!

真是让人热血沸腾啊!!充满干劲儿!!

本期就到这里了!!感谢各位老铁的阅读!!

标签:---,ListNode,--,void,next,链表,LTNode,phead,prev
From: https://blog.51cto.com/u_15808800/6140760

相关文章

  • 使用iperf3工具测试以太网口12小时稳定情况
    以太网接口是一种广泛应用的网络接口,它可以在不同的场合实现不同的功能。例如,它可以把办公室或家庭中的计算机设备连成一个局域网,方便数据共享和网络访问;它也可以把工业控制......
  • 四步教会你如何安装螺杆支撑座
    随着工业自动化的开展,近几年,在数控机床、机器人、机器手以及生产流水线的供需增加,导致了传动部件出现供不应求的状况,尤其是导轨和丝杆,需求量不断增加,作为丝杆的支撑座,需求量......
  • ALLEGRO中放置器件ROOM的使用
    1,打开原理图   这里改原理图的ROOM,第一张原理图填写1,第二章原理图填2,以此类推  这里原理图改好后,重新导入第一方网表,然后切换到PCB文件      ......
  • 使用iperf3工具测试以太网口12小时稳定情况
    以太网接口是一种广泛应用的网络接口,它可以在不同的场合实现不同的功能。例如,它可以把办公室或家庭中的计算机设备连成一个局域网,方便数据共享和网络访问;它也可以把工业控......
  • 爬虫selenium模块
    selenium基本使用selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题可以直接用代码模拟真实的浏览器操作,每一步......
  • 开源周刊第一期
    Codon:让Python拥有C/C++一样的速度为了解决python运行速度,麻省理工学院的计算机科学家出手了,他们共同研发了一种名为Codon的Python编译器,可以将Python代码转......
  • rootkit隐藏端口
    1.基本原理rootkit隐藏的基本步骤是:hook掉某一个系统函数,用自己的函数代替自己的函数调用原函数,然后对于原函数的结果进行处理返回处理结果2.实现2.1应该hook......
  • 基于HDF驱动框架的温度传感器驱动开发
    概述​温度传感器(Temperature)Sensor驱动,对温度传感器进行上电,通过驱动入口,将温度传感器注册到HDF驱动框架,对温度传感器驱动进行初始化,探测器件是否在位,并解析配......
  • 简析开源鸿蒙蓝牙能力
    作者:王石蓝牙功能是无线短距的重要能力,在工作、生活中有很多蓝牙设备,比如车载蓝牙设备,蓝牙耳机,蓝牙键盘。1994年由电信商爱立信发展出这个技术,最初蓝牙的设计是系统创建出......
  • CVPR 2023 | GPT-4与文心一言同台竞技,居然是为了自动驾驶UniAD工作!
    以下文章来源于OpenDriveLab ,作者OpenDriveLa00  前言都说ChatGPT是自然语言处理中技术大魔王,国内百度的文心一言是国内技术一霸,那自动驾驶中的技术魔王,你听过说吗?另外......