双向链表的实现

双向链表的实现

    • [一. 概念与结构](#一. 概念与结构)
    • [二. 双向链表的实现](#二. 双向链表的实现)
      • 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 小时前
WordPress wp2shell 漏洞链完整拆解流程
网络·数据结构·安全·web安全
青 春 记 忆4 小时前
LeetCode 142. 环形链表 II|Python 解法详解
python·leetcode·链表
小欣加油4 小时前
leetcode3069 将元素分配到两个数组中I
数据结构·c++·算法·leetcode·职场和发展
_Narcissus_7 小时前
排序算法总结表格
c语言·数据结构·c++·笔记·算法·排序算法·总结
一只小小的芙厨9 小时前
前缀和与差分
数据结构·算法
一只小小的芙厨9 小时前
最短路总结
数据结构·算法
来一碗刘肉面11 小时前
有向无环图 DAG(描述表达式)
数据结构
郝学胜_神的一滴12 小时前
干货版《算法导论》18:遍历增删原理、时间复杂度与集合序列实现全解
数据结构·算法
BK贝壳13 小时前
Python底层:1亿个布尔值缓存失效标记,list爆内存numpy爆拷贝,bool-hybrid-array混合存储实测
数据结构·python·缓存·性能优化·list·numpy
_Narcissus_13 小时前
B树概念及操作笔记(含完整代码实现)
c语言·数据结构·数据库·c++·笔记·b树·算法