带头双向循环链表的代码总结

今天,我将带来带头双向循环链表的代码总结。





带头双向循环链表的三个文档

List.h--------头文件的引用和函数的声明
List.c--------函数的定义
test.c--------带头双向循环链表的检验



初始化函数

//初始化的函数
SLNode* InitList()
{
	SLNode* Head = (SLNode*)malloc(sizeof(SLNode));
	if (Head == NULL)
	{
		perror("InitList()");
		exit(1);
	}
	Head->next = Head;
	Head->prev = Head;
	Head->val = -1;
}


开辟结点的函数

//开辟结点的函数
SLNode* BuyListNode(SListType x)
{
	SLNode* NewNode = (SLNode*)malloc(sizeof(SLNode));
	if (NewNode == NULL)
	{
		perror("BuyListNode()");
		exit(1);
	}
	NewNode->val = x;
	NewNode->prev = NULL;
	NewNode->next = NULL;
	return NewNode;
}


打印函数

//打印函数
void Print(SLNode* Head)
{
	assert(Head);
	SLNode* cur = Head->next;
	while (cur != Head)
	{
		printf("%d ",cur->val);
		cur = cur->next;
	}
	printf("\n");
}


销毁链表的函数

//销毁链表的函数
void DestroyList(SLNode* Head)
{
	assert(Head);
	SLNode* cur = Head->next;
	while (cur != Head)
	{
		SLNode* Next = cur->next;
		free(cur);
		cur = Next;
	}
	free(cur);
}


统计结点个数的函数

//统计结点的个数
size_t LTsize(SLNode* Head)
{
	assert(Head);
	size_t count = 0;
	SLNode* cur = Head->next;
	while (cur != Head)
	{
		count++;
		cur = cur->next;
	}
	return count;
}


检验链表是否为空的函数

//检验链表是否为空
bool LTEmpty(SLNode* Head)
{
	assert(Head);

	return Head->next == Head;
}


在pos位置插入数据的函数

//在pos位置前插入
void SLInsert(SLNode* pos, SListType x)
{
	assert(pos);
	SLNode* NewNode = BuyListNode(x);
	SLNode* Prev = pos->prev;

	Prev->next = NewNode;
	pos->prev = NewNode;

	NewNode->prev = Prev;
	NewNode->next = pos;
}


删除pos位置数据的函数

//删除pos位置的数据
void SLErase(SLNode* pos)
{
	assert(pos);
	SLNode* Prev = pos->prev;
	SLNode* Next = pos->next;

	free(pos);

	Prev->next = Next;
	Next->prev = Prev;
}


头插和头删函数

//头插
void SLPushFront(SLNode* Head, SListType x)
{
	assert(Head);

	SLInsert(Head->next,x);
}

//头删
void SLPopFront(SLNode* Head)
{ 
	assert(Head);
	assert(Head->next != Head);

	SLErase(Head->next);
}


尾插和尾删函数

//尾插
void SLPushBack(SLNode* Head, SListType x)
{
	assert(Head);
	
	SLInsert(Head,x);
}

//尾删
void SLPopBack(SLNode* Head)
{
	assert(Head);
	assert(Head->prev != Head);

	SLErase(Head->prev);
}


查找函数

//查找函数
SLNode* Find(SLNode* Head, SListType x)
{
	assert(Head);
	SLNode* cur = Head->next;
	while (cur != Head)
	{
		if (cur->val == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}


菜单的实现和函数的调用

void menu()
{
	printf("**************************************************\n");
	printf("***** 1.头插              2.头删             *****\n");
	printf("***** 3.尾插              4.尾删             *****\n");
	printf("***** 5.pos前插入         6.删除pos位置数据  *****\n");
	printf("***** 7.统计结点的个数    8.检验链表是否为空 *****\n");
	printf("***** 9.打印函数          10.查找            *****\n");
	printf("***** 0.退出                                *****\n");
	printf("**************************************************\n");
}

int main()
{
	int input = 0;
	int num = 0;
	int Pos = 0;
	SLNode* Head = InitList();
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("请输入你要插入的数据\n");
			scanf("%d", &num);
			SLPushFront(Head, num);
			break;
		case 2:
			SLPopFront(Head);
			break;
		case 3:
			printf("请输入你要插入的数据\n");
			scanf("%d", &num);
			SLPushBack(Head, num);
			break;
		case 4:
			SLPopBack(Head);
			break;
		case 5:
			printf("请输入你要在哪个数字前插入\n");
			scanf("%d", &Pos);
			printf("请输入你要插入的数据\n");
			scanf("%d", &num);
			SLNode* pos = Find(Head, Pos);
			SLInsert(pos, num);
			break;
		case 6:
			printf("请输入你要删除哪个数据\n");
			scanf("%d", &Pos);
			pos = Find(Head, Pos);
			SLErase(pos);
			break;
		case 7:
			printf("%d\n", LTsize(Head));
			break;
		case 8:
			if (LTEmpty(Head) == true)
				printf("链表为空\n");
			else
				printf("链表非空\n");
			break;
		case 9:
			Print(Head);
			break;
		case 10:
			printf("请输入你要查找的数据\n");
			scanf("%d", &num);
			pos = Find(Head, num);
			if (pos == NULL)
				printf("找不到\n");
			else if (pos->prev == Head)
				printf("头结点\n");
			else if (pos->next == Head)
				printf("尾结点\n");			
			else
				printf("地址是:%x,在数字:%d的后面,%d的前面\n", pos, pos->prev->val, pos->next->val);
			break;
		case 0:
			printf("退出\n");
			DestroyList(Head);
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}


函数的声明

//初始化的函数
 SLNode* InitList();

//开辟结点的函数
 SLNode* BuyListNode(SListType x);

 //打印函数
 void Print(SLNode* Head);

 //销毁链表的函数
 void DestroyList(SLNode* Head);

 //统计结点的个数
 size_t LTsize(SLNode* Head);

 //检验链表是否为空
 bool LTEmpty(SLNode* Head);

 //在pos位置前插入
 void SLInsert(SLNode* pos, SListType x);

//删除pos位置的数据
 void SLErase(SLNode* pos);

 //头插
 void SLPushFront(SLNode* Head, SListType x);

 //头删
 void SLPopFront(SLNode* Head);

 //尾插
 void SLPushBack(SLNode* Head, SListType x);

 //尾删
 void SLPopBack(SLNode* Head);

 //查找函数
 SLNode* Find(SLNode* Head, SListType x);


List.c文档的代码

#define _CRT_SECURE_NO_WARNINGS 1

#include "List.h"

//初始化的函数
SLNode* InitList()
{
	SLNode* Head = (SLNode*)malloc(sizeof(SLNode));
	if (Head == NULL)
	{
		perror("InitList()");
		exit(1);
	}
	Head->next = Head;
	Head->prev = Head;
	Head->val = -1;
}

//开辟结点的函数
SLNode* BuyListNode(SListType x)
{
	SLNode* NewNode = (SLNode*)malloc(sizeof(SLNode));
	if (NewNode == NULL)
	{
		perror("BuyListNode()");
		exit(1);
	}
	NewNode->val = x;
	NewNode->prev = NULL;
	NewNode->next = NULL;
	return NewNode;
}

//打印函数
void Print(SLNode* Head)
{
	assert(Head);
	SLNode* cur = Head->next;
	while (cur != Head)
	{
		printf("%d ",cur->val);
		cur = cur->next;
	}
	printf("\n");
}

//销毁链表的函数
void DestroyList(SLNode* Head)
{
	assert(Head);
	SLNode* cur = Head->next;
	while (cur != Head)
	{
		SLNode* Next = cur->next;
		free(cur);
		cur = Next;
	}
	free(cur);
}

//统计结点的个数
size_t LTsize(SLNode* Head)
{
	assert(Head);
	size_t count = 0;
	SLNode* cur = Head->next;
	while (cur != Head)
	{
		count++;
		cur = cur->next;
	}
	return count;
}

//检验链表是否为空
bool LTEmpty(SLNode* Head)
{
	assert(Head);

	return Head->next == Head;
}

//在pos位置前插入
void SLInsert(SLNode* pos, SListType x)
{
	assert(pos);
	SLNode* NewNode = BuyListNode(x);
	SLNode* Prev = pos->prev;

	Prev->next = NewNode;
	pos->prev = NewNode;

	NewNode->prev = Prev;
	NewNode->next = pos;
}

//删除pos位置的数据
void SLErase(SLNode* pos)
{
	assert(pos);
	SLNode* Prev = pos->prev;
	SLNode* Next = pos->next;

	free(pos);

	Prev->next = Next;
	Next->prev = Prev;
}

//头插
void SLPushFront(SLNode* Head, SListType x)
{
	assert(Head);

	SLInsert(Head->next,x);
}

//头删
void SLPopFront(SLNode* Head)
{ 
	assert(Head);
	assert(Head->next != Head);

	SLErase(Head->next);
}

//尾插
void SLPushBack(SLNode* Head, SListType x)
{
	assert(Head);
	
	SLInsert(Head,x);
}

//尾删
void SLPopBack(SLNode* Head)
{
	assert(Head);
	assert(Head->prev != Head);

	SLErase(Head->prev);
}

//查找函数
SLNode* Find(SLNode* Head, SListType x)
{
	assert(Head);
	SLNode* cur = Head->next;
	while (cur != Head)
	{
		if (cur->val == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}


List.h文档的代码

#pragma once

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>

typedef int SListType;
typedef struct ListNode
{
	SListType val;
	struct ListNode* prev;
	struct ListNode* next;
}SLNode;

//初始化的函数
 SLNode* InitList();

//开辟结点的函数
 SLNode* BuyListNode(SListType x);

 //打印函数
 void Print(SLNode* Head);

 //销毁链表的函数
 void DestroyList(SLNode* Head);

 //统计结点的个数
 size_t LTsize(SLNode* Head);

 //检验链表是否为空
 bool LTEmpty(SLNode* Head);

 //在pos位置前插入
 void SLInsert(SLNode* pos, SListType x);

//删除pos位置的数据
 void SLErase(SLNode* pos);

 //头插
 void SLPushFront(SLNode* Head, SListType x);

 //头删
 void SLPopFront(SLNode* Head);

 //尾插
 void SLPushBack(SLNode* Head, SListType x);

 //尾删
 void SLPopBack(SLNode* Head);

 //查找函数
 SLNode* Find(SLNode* Head, SListType x);


test.c文档的代码

#define _CRT_SECURE_NO_WARNINGS 1

#include "List.h"

void menu()
{
	printf("**************************************************\n");
	printf("***** 1.头插              2.头删             *****\n");
	printf("***** 3.尾插              4.尾删             *****\n");
	printf("***** 5.pos前插入         6.删除pos位置数据  *****\n");
	printf("***** 7.统计结点的个数    8.检验链表是否为空 *****\n");
	printf("***** 9.打印函数          10.查找            *****\n");
	printf("***** 0.退出                                *****\n");
	printf("**************************************************\n");
}

int main()
{
	int input = 0;
	int num = 0;
	int Pos = 0;
	SLNode* Head = InitList();
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("请输入你要插入的数据\n");
			scanf("%d", &num);
			SLPushFront(Head, num);
			break;
		case 2:
			SLPopFront(Head);
			break;
		case 3:
			printf("请输入你要插入的数据\n");
			scanf("%d", &num);
			SLPushBack(Head, num);
			break;
		case 4:
			SLPopBack(Head);
			break;
		case 5:
			printf("请输入你要在哪个数字前插入\n");
			scanf("%d", &Pos);
			printf("请输入你要插入的数据\n");
			scanf("%d", &num);
			SLNode* pos = Find(Head, Pos);
			SLInsert(pos, num);
			break;
		case 6:
			printf("请输入你要删除哪个数据\n");
			scanf("%d", &Pos);
			pos = Find(Head, Pos);
			SLErase(pos);
			break;
		case 7:
			printf("%d\n", LTsize(Head));
			break;
		case 8:
			if (LTEmpty(Head) == true)
				printf("链表为空\n");
			else
				printf("链表非空\n");
			break;
		case 9:
			Print(Head);
			break;
		case 10:
			printf("请输入你要查找的数据\n");
			scanf("%d", &num);
			pos = Find(Head, num);
			if (pos == NULL)
				printf("找不到\n");
			else if (pos->prev == Head)
				printf("头结点\n");
			else if (pos->next == Head)
				printf("尾结点\n");			
			else
				printf("地址是:%x,在数字:%d的后面,%d的前面\n", pos, pos->prev->val, pos->next->val);
			break;
		case 0:
			printf("退出\n");
			DestroyList(Head);
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

今天的带头双向循环链表的代码总结就到这里,关注点一点,下期更精彩。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值