双链表(纯代码)

list.h

cpp 复制代码
#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

cpp 复制代码
#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

cpp 复制代码
#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;
}
相关推荐
丰锋ff7 分钟前
设计模式学习笔记
笔记·学习·设计模式
罗西的思考12 分钟前
【OpenClaw具身硬件】ZeroClaw 源码阅读笔记(1)— 总体
人工智能·笔记·深度学习·机器学习
loopne1 小时前
AI网文写作实验笔记(十三):系列总结——12 篇实验、8 条核心结论,把“AI 写小说“每一步拆开验证
人工智能·经验分享·笔记·ai写作·智能写作
M78佐菲1 小时前
Linux多线程:创建、回收与互斥同步
linux·笔记·学习·算法
小手cool1 小时前
使用递归对数组进行反转操作
java·数据结构·算法
码行山野赴时序归途2 小时前
从暴力到最优:三道 C 语言入门题的解法思路
c语言·开发语言·数据结构·算法·leetcode·排序算法
sunoo-2292 小时前
【Linux 系统编程】学习第七天:线程属性 | 互斥锁 | 死锁 | 信号量 核心知识点 + 踩坑实战
linux·c语言·笔记·vscode·学习
LccKyI2 小时前
C#基础编程 面试题汇总(三)
笔记·c#
懿路向前2 小时前
【HarmonyOS学习笔记】2026-08-27 | 端插件踩坑与设计取舍
笔记·学习·harmonyos
ouynagda3 小时前
Linux多线程:互斥锁与信号量学习笔记
linux·笔记·学习