双链表(纯代码)

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;
}
相关推荐
张杰萌萌哒13 分钟前
点云配准ICP算法笔记
笔记·点云匹配
NuyoahC28 分钟前
算法笔记(四)——模拟
c++·笔记·模拟算法
LearnTech_12331 分钟前
【学习笔记】手写 Tomcat 八
java·笔记·学习·tomcat·手写 tomcat
宇宙超粒终端控制中心1 小时前
leetcode35--搜索插入位置--二分查找刷题
数据结构·二分查找
凡人的AI工具箱2 小时前
15分钟学 Python 第31天 :Web Scraping
开发语言·数据结构·人工智能·python·算法
samroom2 小时前
前端学习第一天笔记 HTML5 CSS初学以及VSCODE中的常用快捷键
前端·css·笔记·学习·html5
single5943 小时前
【优选算法】(第十五篇)
java·数据结构·c++·vscode·算法·leetcode
CrazyZ1264 小时前
c++primer第十三章 类继承
开发语言·c++·笔记·学习
我命由我123454 小时前
8.使用 VSCode 过程中的英语积累 - Help 菜单(每一次重点积累 5 个单词)
ide·经验分享·笔记·vscode·学习·编辑器·学习方法