双向链表的实现

双向链表的实现

    • [一. 概念与结构](#一. 概念与结构)
    • [二. 双向链表的实现](#二. 双向链表的实现)
      • 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;
}
相关推荐
LYFlied3 小时前
【每日算法】LeetCode 153. 寻找旋转排序数组中的最小值
数据结构·算法·leetcode·面试·职场和发展
jianfeng_zhu5 小时前
整数数组匹配
数据结构·c++·算法
yueqingll5 小时前
032、数据结构之代码时间复杂度和空间复杂度的判断:从入门到实战
数据结构
罗湖老棍子9 小时前
最小函数值(minval)(信息学奥赛一本通- P1370)
数据结构·c++·算法··优先队列·
鹿角片ljp9 小时前
力扣 83: 删除排序链表中的重复元素(Java实现)
java·leetcode·链表
LYFlied9 小时前
【每日算法】LeetCode 208. 实现 Trie (前缀树)
数据结构·算法·leetcode·面试·职场和发展
AI科技星10 小时前
统一场论框架下万有引力常数的量子几何涌现与光速关联
数据结构·人工智能·算法·机器学习·重构
仰泳的熊猫10 小时前
1109 Group Photo
数据结构·c++·算法·pat考试
2401_8414956410 小时前
【数据结构】最短路径的求解
数据结构·动态规划·贪心·ipython·最短路径·迪杰斯特拉算法·弗洛伊德算法
tgethe10 小时前
Java 数组(Array)笔记:从语法到 JVM 内核
java·数据结构