双向链表的实现

双向链表的实现

    • [一. 概念与结构](#一. 概念与结构)
    • [二. 双向链表的实现](#二. 双向链表的实现)
      • 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;
}
相关推荐
ValhallaCoder7 小时前
hot100-二叉树I
数据结构·python·算法·二叉树
月挽清风8 小时前
代码随想录第十五天
数据结构·算法·leetcode
NEXT068 小时前
前端算法:从 O(n²) 到 O(n),列表转树的极致优化
前端·数据结构·算法
小妖66612 小时前
js 实现快速排序算法
数据结构·算法·排序算法
独好紫罗兰14 小时前
对python的再认识-基于数据结构进行-a003-列表-排序
开发语言·数据结构·python
wuhen_n14 小时前
JavaScript内置数据结构
开发语言·前端·javascript·数据结构
2401_8414956414 小时前
【LeetCode刷题】二叉树的层序遍历
数据结构·python·算法·leetcode·二叉树··队列
独好紫罗兰15 小时前
对python的再认识-基于数据结构进行-a002-列表-列表推导式
开发语言·数据结构·python
2401_8414956415 小时前
【LeetCode刷题】二叉树的直径
数据结构·python·算法·leetcode·二叉树··递归
数智工坊15 小时前
【数据结构-树与二叉树】4.5 线索二叉树
数据结构