双向链表的实现

双向链表的实现

    • [一. 概念与结构](#一. 概念与结构)
    • [二. 双向链表的实现](#二. 双向链表的实现)
      • 2.1头文件
      • [2.2 实现函数](#2.2 实现函数)
      • [2.3 测试函数](#2.3 测试函数)

一. 概念与结构

带头双向循环链表:

带头双向循环链表中的头节点其实是哨兵位,不存储任何有效的数字,只用来占位。

二. 双向链表的实现

2.1头文件

c 复制代码
#include<stdlib.h>
#include<stdio.h>
#include<assert.h>
#include<stdbool.h>
typedef int DateType;
typedef struct ListNode
{
	DateType date;
	struct ListNode* next;
	struct ListNode* prev;
}ListNode;
//初始化
void LTInit(ListNode** pphead);
//销毁
void LTDestory(ListNode** phead);
//申请新节点
ListNode* LTBuyNode(DateType x);
//打印链表
void LTPrint(ListNode* phead);
//尾插&&头插
void LTPushBack(ListNode* phead, DateType x);
void LTPushFront(ListNode* phead, DateType x);
//判空
bool LTEmpty(ListNode* phead);
//尾删&&头删
void LTPopBack(ListNode* phead);
void LTPopFront(ListNode* phead);
//查找
ListNode* LTFind(ListNode* phead, DateType x);
//在pos后插入数据
void LTInsert(ListNode* pos, DateType x);
//删除pos节点的位置
void LTErase(ListNode* pos);

2.2 实现函数

c 复制代码
#include"ListNode.h"
//初始化
void LTInit(ListNode** pphead)
{
	//*pphead = (ListNode*)malloc(sizeof(ListNode));
	//if (*pphead == NULL)
	//{
	//	perror("malloc");
	//	exit(1);
	//}
	//(*pphead)->date = -1;
	//(*pphead)->next = (*pphead)->prev = *pphead;
	*pphead = LTBuyNode(-1);
}
//申请新节点
ListNode* LTBuyNode(DateType x)
{
	ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
	if (newnode == NULL)
	{
		perror("malloc");
		exit(1);
	}
	newnode->date = x;
	newnode->next = newnode->prev = newnode;
}
//销毁
void LTDestory(ListNode** pphead)
{
	ListNode* pcur = (*pphead)->next;
	while (pcur != *pphead)
	{
		ListNode* pnext = pcur->next;
		free(pcur);
		pcur = pnext;
	}
	free(*pphead);
	*pphead = NULL;
}


//打印链表
void LTPrint(ListNode* phead)
{
	assert(phead);
	ListNode* pcur = phead->next;
	while (pcur!= phead)
	{
		printf("%d->", pcur->date);
		pcur = pcur->next;
	}
	printf("\n");
}
//尾插
void LTPushBack(ListNode* phead, DateType x)
{
	assert(phead);
	ListNode* newnode = LTBuyNode(x);
	newnode->next = phead;
	newnode->prev = phead->prev;
	phead->prev->next = newnode;
	phead->prev = newnode;
}
//头插
void LTPushFront(ListNode* phead, DateType x)
{
	assert(phead);
	ListNode* newnode = LTBuyNode(x);
	newnode->prev = phead;
	newnode->next = phead->next;
	phead->next->prev = newnode;
	phead->next = newnode;
}
//判空
bool LTEmpty(ListNode* phead)
{
	assert(phead);
	return phead->next == phead;
}



//尾删
void LTPopBack(ListNode* phead)
{
	assert(!LTEmpty(phead));
	ListNode* del = phead->prev;
	del->prev->next = phead;
	phead -> prev = del->prev;
	free(del);
	del = NULL;
}
//头删
void LTPopFront(ListNode* phead)
{
	assert(!LTEmpty(phead));
	ListNode* del = phead->next;
	del->next->prev = phead;
	phead->next = del->next;
	free(del);
	del = NULL;
}
//查找
ListNode* LTFind(ListNode* phead, DateType x)
{
	assert(phead);
	ListNode* pcur = phead->next;
	while (pcur != phead)
	{
		if (pcur->date == x)
		{
			return pcur;
		}
		pcur = pcur->next;
	}
	return NULL;
}
//在pos后插入数据
void LTInsert(ListNode* pos, DateType x)
{
	assert(pos);
	ListNode* newnode = LTBuyNode(x);
	newnode->next = pos->next;
	newnode->prev = pos;
	pos->next->prev = newnode;
	pos->next = newnode;
}
//删除pos节点的位置
void LTErase(ListNode* pos)
{
	assert(pos);
	pos->prev->next = pos->next;
	pos->next->prev = pos->prev;
	free(pos);
	pos = NULL;
}

2.3 测试函数

c 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include"ListNode.h"
void test01()
{
	ListNode* phead = NULL;
	LTInit(&phead);
	//LTPushBack(phead, 1);
	//LTPrint(phead);
	//LTPushBack(phead, 2);
	//LTPrint(phead);
	//LTPushBack(phead, 3);
	//LTPrint(phead);
	//LTPushBack(phead, 4);
	//LTPrint(phead);

	//LTPushFront(phead, 5);
	//LTPrint(phead);
	//LTPushFront(phead, 6);
	//LTPrint(phead);
	//LTPushFront(phead, 7);
	//LTPrint(phead);
	//LTPushFront(phead, 8);
	//LTPrint(phead);

	/*LTPushBack(phead, 1);
	LTPushBack(phead, 2);
	LTPushBack(phead, 3);
	LTPushBack(phead, 4);
	LTPrint(phead);*/
	//LTPopBack(phead);
	//LTPrint(phead);
	//LTPopBack(phead);
	//LTPrint(phead);
	//LTPopBack(phead);
	//LTPrint(phead);
	//LTPopBack(phead);
	//LTPrint(phead);

	LTPushBack(phead, 1);
	LTPushBack(phead, 2);
	LTPushBack(phead, 3);
	LTPushBack(phead, 4);
	//LTPrint(phead);
	//LTPopFront(phead);
	//LTPrint(phead);
	//LTPopFront(phead);
	//LTPrint(phead);
	//LTPopFront(phead);
	//LTPrint(phead);
	//LTPopFront(phead);
	//LTPrint(phead);
	/*LTPopFront(phead);*/

	ListNode* pos = LTFind(phead, 2);
	if (pos != NULL)
	{
		printf("找到了\n");
	}
	else
	{
		printf("没找到\n");
	}
	//LTInsert(pos, 100);
	//LTPrint(phead);
	LTErase(pos);
	LTPrint(phead);
	LTDestory(&phead);
}
int main()
{
	test01();
	return 0;
}
相关推荐
量子炒饭大师1 小时前
【一天一个计算机知识】—— 【编程百度】悬空指针
c语言·数据结构·c++·git·安全·github·dubbo
吃着火锅x唱着歌1 小时前
LeetCode 624.数组列表中的最大距离
数据结构·算法·leetcode
fei_sun1 小时前
【数据结构】2019年真题
数据结构
Mz122110 小时前
day05 移动零、盛水最多的容器、三数之和
数据结构·算法·leetcode
complexor10 小时前
NOIP 2025 游记
数据结构·数学·动态规划·贪心·组合计数·树上问题·游记&总结
牢七11 小时前
数据结构1111
数据结构
却话巴山夜雨时i11 小时前
74. 搜索二维矩阵【中等】
数据结构·算法·矩阵
sin_hielo11 小时前
leetcode 3512
数据结构·算法·leetcode