双向链表的实现

双向链表的实现

    • [一. 概念与结构](#一. 概念与结构)
    • [二. 双向链表的实现](#二. 双向链表的实现)
      • 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;
}
相关推荐
666HZ6661 天前
数据结构2.0 线性表
c语言·数据结构·算法
余瑜鱼鱼鱼1 天前
Java数据结构:从入门到精通(十二)
数据结构
一叶知秋061 天前
数据结构-什么是队列?
数据结构·队列
Jasmine_llq1 天前
《CF280C Game on Tree》
数据结构·算法·邻接表·深度优先搜索(dfs)·树的遍历 + 线性累加统计
zhongvv1 天前
对单片机C语言指针的一些理解
c语言·数据结构·单片机·指针·汇编语言
im_AMBER1 天前
Leetcode 102 反转链表
数据结构·c++·学习·算法·leetcode·链表
Xの哲學1 天前
深入剖析Linux文件系统数据结构实现机制
linux·运维·网络·数据结构·算法
C雨后彩虹1 天前
竖直四子棋
java·数据结构·算法·华为·面试
荒诞硬汉1 天前
对象数组.
java·数据结构
散峰而望1 天前
【算法竞赛】栈和 stack
开发语言·数据结构·c++·算法·leetcode·github·推荐算法