初阶数据结构的实现2 双向链表

1.双向链表

1.1 概念与结构

在这里插入图片描述

1.2实现双向链表

1.2.1定义程序目标

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
typedef int LTDateType;
//定义双向链表结构
typedef struct ListNode {
	LTDateType data;
	ListNode* prev;
	ListNode* next;
}ListNode;
//
ListNode* BuyNode(LTDateType x);
//初始化
void LTInitialise(ListNode** pphead);
//销毁
void LTDestroy(ListNode** pphead);
//尾插
void LTPushBack(ListNode* phead, LTDateType x);
//头插
void LTPushFront(ListNode* phead, LTDateType x);
//打印双向链表
void LTPrint(ListNode* phead);
//判断链表是否为空
bool LTEmpty(ListNode* phead);
//尾删
void PopBack(ListNode* phead);
//头删 
void PopFront(ListNode* phead);
//在pos后插入结点
void LTInsert(ListNode* pos, LTDateType x);
//删除指定位置的结点
void LTEraser(ListNode* pos);

1.2.2 设计程序

面向程序员自身的,能实现包括链表的结构定义、初始化、插入、删除、查找、遍历、排序等操作

1.2.3编写代码

#define _CRT_SECURE_NO_WARNINGS 1
#include"list.h"
ListNode* BuyNode(LTDateType x)
{
	ListNode* NewNode = malloc(sizeof(ListNode));
	if (NewNode == NULL)
	{
		perror("Malloc Fail!");
		exit(1);
	}
	NewNode->data = x;
	NewNode->next = NewNode->prev = NewNode;
}

void LTInitialise(ListNode** pphead)
{
	//创建一个头结点(哨兵卫)
	*pphead = BuyNode(-1);
}
//ListNode* LTInitialise()
//{
//	return BuyNode(-1);
//}
void LTDestory(ListNode** pphead)
{
	assert(*pphead && pphead);
	ListNode*pcur = (*pphead)->next;
	while (pcur!=*pphead)
	{
		ListNode* Next = pcur->next;
		free(pcur);
		pcur = Next;
	}
	free(*pphead);
	*pphead = NULL;
	pcur = NULL;
}
//void LTDestory(ListNode* phead)
//{
//	assert(phead);
//	ListNode* pcur = phead->next;
//	while (pcur != phead)
//	{
//		ListNode* Next = pcur->next;
//		free(pcur);
//		pcur = Next;
//	}
//	free(phead);
//	phead = NULL;
//	pcur = NULL;//实参手动置为空或者重新封装一个函数
//}
void LTPushBack(ListNode* phead, LTDateType x)
{
	assert(phead);
	ListNode* NewNode = BuyNode(x);
	NewNode->next = phead;
	NewNode->prev = phead->prev;
	phead->prev->next = NewNode;
	phead->prev = NewNode;
}

void LTPushFront(ListNode* phead, LTDateType x)
{
	assert(phead);
	ListNode* NewNode = BuyNode(x);
	NewNode->prev = phead;
	NewNode->next = phead->next;
	phead->next->prev = NewNode;
}

//打印双向链表
void LTPrint(ListNode* phead)
{
	ListNode* pcur = phead->next;
	while (pcur != phead)
	{
		printf("%d->", pcur->data);
		pcur = pcur->next;
	}
	printf("\n");
}

bool LTEmpty(ListNode* phead)
{
	if (phead->next == phead)
		return false;
	else
		return true;
}

void PopBack(ListNode* phead)
{
	assert(phead);
	assert(LTEmpty(phead));
	ListNode* del = phead->prev;
	ListNode* prev = del->prev;
	prev->next = phead;
	phead->prev = prev;
	free(del);
	del = NULL;
}

void PopFront(ListNode* phead)
{
	assert(phead);
	assert(LTEmpty(phead));
	ListNode* del = phead->next;
	ListNode* Next = del->next;
	Next->prev = phead;
	phead->next = Next;
	free(del);
	del = NULL;
}

ListNode* LTFind(ListNode* phead, LTDateType x)
{
	ListNode* pcur = phead->next;
	while (pcur != phead)
	{
		if (pcur->data == x)
		{
			return pcur;
		}
		pcur = pcur->next;
	}
	return NULL;
}

void LTInsert(ListNode* pos,LTDateType x)
{
	assert(pos);
	ListNode* NewNode = BuyNode(x);
	NewNode->next = pos->next;
	NewNode->prev = pos;
	pos->next->prev = NewNode;
	pos->next = NewNode;
}
void LTEraser(ListNode* pos)
{
	assert(pos);
	pos->prev->next = pos->next;
	pos->next->prev = pos->prev;

	free(pos);
	pos = NULL;
}

1.2.3测试和调试代码

#define _CRT_SECURE_NO_WARNINGS 1
#include"List.h"

void ListTest01()
{
	//创建双向链表变量
	ListNode* plist = NULL;
	LTInitialise(&plist);

	/*ListNode* plist = LTInit();*/

	LTPushBack(plist, 1);
	LTPushBack(plist, 2);
	LTPushBack(plist, 3);
	LTPushBack(plist, 4);
	LTPrint(plist);
	LTPushFront(plist, 1);
	LTPrint(plist);
	LTPushFront(plist, 2);
	LTPrint(plist);
	LTPushFront(plist, 3);
	LTPrint(plist);
	LTPushFront(plist, 4);
	LTPrint(plist);
	
	LTPopBack(plist);
	LTPrint(plist);
	LTPopBack(plist);
	LTPrint(plist);
	LTPopBack(plist);
	LTPrint(plist);
	LTPopBack(plist);
	LTPrint(plist);
	LTPopBack(plist);
	LTPrint(plist);
	/*LTPopFront(plist);
	LTPrint(plist);
	LTPopFront(plist);
	LTPrint(plist);
	LTPopFront(plist);
	LTPrint(plist);
	LTPopFront(plist);
	LTPrint(plist);
	LTPopFront(plist);
	LTPrint(plist);*/

	ListNode* pos = LTFind(plist, 3);
	if (pos == NULL)
	{
		printf("没有找到!\n");
	}
	else
	{
		printf("找到了!\n");
	}
	LTInsert(pos, 11);
	LTPrint(plist);
	LTErase(pos);
	LTPrint(plist);

	LTDestroy(&plist);
	/*LTDestroy2(plist);*/
	plist = NULL;
}
int main()
{
	ListTest01();
	return 0;
}

在这里插入图片描述

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值