双链表(纯代码)
最编程
2024-10-02 07:07:24
...
list.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int LTDatatype;
//定义双向链表的结构
typedef struct ListNode
{
LTDatatype data;
struct ListNode* next;
struct ListNode* prev;
}LTN;
//初始化
void LTInit(LTN** pphead);
//尾插
void LTPushback(LTN* phead,LTDatatype x);
//打印
void LTPrint(LTN* phead);
//头插
LTPPushFront(LTN* phead, LTDatatype x);
//尾删
void LTPopBack(LTN* phead);
//头删
void LTPopFront(LTN* phead);
//查找数据
LTN* LTFind(LTN* phead, LTDatatype x);
//在指定位置后插入数据 若要改成指定位置之前直接传pos->prev即可
void LTInsert(LTN* pos, LTDatatype x);
//删除指定节点
void LTErase(LTN* pos);
//链表的销毁
void LTDestory(LTN* phead);
list.c
#include"list.h"
//申请节点
LTN* LTBuyNode(LTDatatype x)
{
LTN* node = (LTN*)malloc(sizeof(LTN));
if (node == NULL)
{
perror("malloc fail!");
exit(1);
}
node->data = x;
node->next = node->prev = node;
return node;
}
//初始化
void LTInit(LTN** pphead)
{
//给双向链表创建一个哨兵卫
*pphead = LTBuyNode(-1);
}
//打印
void LTPrint(LTN* phead)
{
LTN* pcur = phead->next;
while (pcur != phead)
{
printf("%d->", pcur->data);
pcur = pcur->next;
}
printf("\n");
}
//尾插
void LTPushback(LTN* phead,LTDatatype x)
{
assert(phead);
LTN* newnode = LTBuyNode(x);
newnode->prev = phead->prev;
newnode->next = phead;
phead->prev->next= newnode;
phead->prev = newnode;
}
//头插
LTPPushFront(LTN* phead, LTDatatype x)
{
assert(phead);
LTN* newnode = LTBuyNode(x);
newnode->next = phead->next;
newnode->prev = phead;
phead->next->prev = newnode;
phead->next = newnode;
}
//尾删
void LTPopBack(LTN* phead)
{
//链表必须有效且不能为空
//只有哨兵卫说明是空链表 phead->next=phead;
//哨兵卫为空说明这不是一个有效的双向链表
assert(phead && phead->next != phead);
LTN* del = phead->prev;
del->prev->next = phead;
phead->prev = del->prev;
//删除del节点
free(del);
del = NULL;
}
//头删
void LTPopFront(LTN* phead)
{
assert(phead && phead->next != phead);
LTN* del = phead->next;
phead->next = del->next;
del->next->prev = phead;
//删除del节点
free(del);
del = NULL;
}
//查找数据
LTN* LTFind(LTN* phead, LTDatatype x)
{
LTN* pcur = phead->next;
while (pcur != phead)
{
if (pcur->data == x)
{
printf("找到啦!\n");
return pcur;
}
pcur = pcur->next;
}
//没有找到
printf("没找到。\n");
return NULL;
}
//在指定位置后插入数据
void LTInsert(LTN* pos, LTDatatype x)
{
assert(pos);
LTN* newnode = LTBuyNode(x);
newnode->next = pos->next;
newnode->prev = pos;
pos->next->prev = newnode;
pos->next = newnode;
}
//删除指定节点
void LTErase(LTN* pos)
{
//理论上来说不能为phead,但是没有参数phead,无法增加校验
assert(pos);
pos->next->prev = pos->prev;
pos->prev->next = pos->next;
free(pos);
pos = NULL;
}
//链表的销毁
void LTDestory(LTN* phead)
{
assert(phead);
LTN* pcur = phead->next;
while (pcur != phead)
{
LTN* next = pcur->next;
free(pcur);
pcur = next;
}
//此时pcur指向的是phead,但是phead还没有被销毁
free(phead);
phead = NULL;
}
test.c
#include"list.h"
void listtest01(void)
{
LTN*plist=NULL;
LTInit(&plist);
LTPushback(plist, 3);
LTPushback(plist, 4);
LTPPushFront(plist, 5);
LTPopBack(plist);
LTPopFront(plist);
LTN*ret=LTFind(plist, 3);
LTInsert(ret, 99);
LTPrint(plist);
LTErase(ret);
ret = NULL;
LTPrint(plist);
LTDestory(plist);
plist = NULL;
}
int main(void)
{
listtest01();
return 0;
}
上一篇: SkyWalking 定制链接追踪
下一篇: UE5.4.3 重放 重放系统
推荐阅读
-
电源按钮 237。删除链表 [Ravens] 中的节点 - 代码
-
LIST 仿真实现的 C++(代码纯享版) - I. 代码
-
双链表(纯代码)
-
通过新增二分功能和纠正复制移动错误,完善C++课程设计中通讯录管理系统的纯代码版本。
-
玩转双链表:从基础概念到实战应用 - 包括创建(初始化、头尾添加)、插入、搜索、删除及判空等核心操作总结
-
在 Android Studio 中直接执行纯 Java 代码
-
数据结构:双链表的 C 语言实现 - I. 链表的分类
-
数据结构 - 单链表和双链表(Java 实现)
-
平面纯弯曲梁单元的 Matlab 有限元编程 | 欧拉梁单元 | 简支梁 | 悬臂梁 | 弯矩图 | 变形图 | Matlab 源代码 | 视频教程
-
短视频完善开源源代码背景+APP双端源代码 - 简介