C语言》环形双链表增、删、查、改、销毁

《C语言》环形双链表增、删、查、改、销毁

Main.c

#include "A_DoubleList.h"
#include <time.h>


#define N 10

void main()
{

/********************尾部添加节点********************/

#if 0
	//声明一个结构体(保存头指针和尾指针)
	A_DoubleList Head;
	//初始化结构体
	InitList(&Head);

	for (int i = 0; i < 1; i++)
	{
		//循环添加数据
		PushBack(&Head,i);
	}
	puts("正向打印:");
	Show(&Head);

	puts("\n反向打印:");
	ReverseShow(&Head);
#endif

/********************尾部添加节点********************/

#if 0
	//声明一个结构体(保存头指针和尾指针)
	A_DoubleList Head;
	//初始化结构体
	InitList(&Head);

	for (int i = 0; i < N; i++)
	{
		//循环添加数据
		PushHead(&Head, i);
	}
	puts("正向打印:");
	Show(&Head);

	puts("\n反向打印:");
	ReverseShow(&Head);
#endif
	

/********************查找指定节点********************/

#if 0
	//声明一个结构体(保存头指针和尾指针)
	A_DoubleList Head;
	//初始化结构体
	InitList(&Head);

	for (int i = 0; i < N; i++)
	{
		//循环添加数据
		PushBack(&Head, i);
	}
	puts("正向打印:");
	Show(&Head);

	puts("\n查找结果:");
	Node* P_Res = FindNode(&Head, 0);

	NULL != P_Res ? printf("%d\n",P_Res->Data): puts("Can't find.");

	P_Res = FindNode(&Head, 5);
	NULL != P_Res ? printf("%d\n", P_Res->Data) : puts("Can't find.");

	P_Res = FindNode(&Head, 9);
	NULL != P_Res ? printf("%d\n", P_Res->Data) : puts("Can't find.");

	P_Res = FindNode(&Head, 2018);
	NULL != P_Res ? printf("%d\n", P_Res->Data) : puts("Can't find.");
#endif


/********************将节点插入指定位置********************/

#if 0
	//声明一个结构体(保存头指针和尾指针)
	A_DoubleList Head;
	//初始化结构体
	InitList(&Head);


	for (int i = 0; i < N; i++)
	{
		//循环添加数据
		PushBack(&Head, i);
	}
	
	puts("正向打印:\n");
	Show(&Head);

	InsertNode(&Head, 0, 2018);
	InsertNode(&Head, 5, 2018);
	InsertNode(&Head, 9, 2018);

	puts("插入数据之后:");
	Show(&Head);

#endif

/********************修改指定节点的值********************/

#if 0
	//声明一个结构体(保存头指针和尾指针)
	A_DoubleList Head;
	//初始化结构体
	InitList(&Head);


	for (int i = 0; i < 10; i++)
	{
		//循环添加数据
		PushBack(&Head, i);
	}

	puts("正向打印:\n");
	Show(&Head);

	Modification(&Head, 0, 2018);
	Modification(&Head, 5, 2018);
	Modification(&Head, 9, 2018);

	Show(&Head);
#endif


/********************删除指定节点********************/

#if 0
	//声明一个结构体(保存头指针和尾指针)
	A_DoubleList Head;
	//初始化结构体
	InitList(&Head);


	for (int i = 0; i < 10; i++)
	{
		//循环添加数据
		PushBack(&Head, i);
	}

	puts("正向打印:\n");
	Show(&Head);

	DeleteNode(&Head, 0);
	DeleteNode(&Head, 5);
	DeleteNode(&Head, 9);


	puts("节点删除之后:\n");
	Show(&Head);
#endif

/********************删除指定节点********************/

#if 0
	//声明一个结构体(保存头指针和尾指针)
	A_DoubleList Head;
	//初始化结构体
	InitList(&Head);


	for (int i = 0; i < 10; i++)
	{
		//循环添加数据
		PushBack(&Head, i);
	}

	puts("正向打印:\n");
	Show(&Head);

	Destory(&Head);

	puts("链表销毁\n");
	Show(&Head);
#endif 


	system("pause");
}

A_DoubleList.h

#pragma once 



#ifdef __cplusplus
extern "C"
{
#endif

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

	typedef int DataType;

	typedef struct Node
	{
		DataType Data;
		
		//前驱
		struct Node* P_Pre;
		//后继
		struct Node* P_Next;
	}Node;

	typedef struct A_DoubleList
	{
		//头指针
		Node* P_Head;
		//尾指针
		Node* P_Tail;
	}A_DoubleList;

	//初始化双链表
	void InitList(A_DoubleList* P_List);
	//初始化节点
	void InitNode(Node* P_Node,DataType Data);
	//正向显示链表
	void Show(A_DoubleList* P_List);
	//反向显示链表
	void ReverseShow(A_DoubleList* P_List);
	//尾部添加节点
	void PushBack(A_DoubleList* P_List, DataType Data);
	//头部添加节点
	void PushHead(A_DoubleList* P_List, DataType Data);
	//查找指定节点
	Node* FindNode(A_DoubleList* P_List, DataType Data);
	//将节点插入指定位置
	void InsertNode(A_DoubleList* P_List, DataType Rear,DataType InsData);
	//修改指定节点的值
	void Modification(A_DoubleList* P_List, DataType OldData, DataType NewData);
	//删除指定节点
	void DeleteNode(A_DoubleList* P_List, DataType DelData);
	//销毁链表
	void Destory(A_DoubleList* P_List);
	
#ifdef __cplusplus
}
#endif

A_DoubleList.c

#include "A_DoubleList.h"



//初始化双链表
void InitList(A_DoubleList* P_List)
{
	P_List->P_Head = P_List->P_Tail = NULL;
}

//初始化节点
void InitNode(Node* P_Node, DataType Data)
{
	
	P_Node->P_Pre = P_Node->P_Next = NULL;
	P_Node->Data = Data;
}

//正向显示链表
void Show(A_DoubleList* P_List)
{
	
	//没有节点
	if (NULL ==P_List->P_Head&&NULL==P_List->P_Tail)
	{
		//直接返回
		return;
	}
	else if (P_List->P_Head == P_List->P_Tail)
	{
		//只有一个节点
		printf("%p\t%p\t%p\t%d\n", P_List->P_Head,P_List->P_Head->P_Pre,P_List->P_Head->P_Next,P_List->P_Head->Data);
	}
	else
	{
		//头节点
		Node* P_Bak =P_List->P_Head;
		while (P_Bak!= P_List->P_Tail)
		{
			printf("%p\t%p\t%p\t%d\n", P_Bak, P_Bak->P_Pre, P_Bak->P_Next, P_Bak->Data);
			P_Bak = P_Bak->P_Next;
		}
		//补充最后一次打印
		printf("%p\t%p\t%p\t%d\n", P_Bak, P_Bak->P_Pre, P_Bak->P_Next, P_Bak->Data);
	}

	puts("");
}

//反向显示链表
void ReverseShow(A_DoubleList* P_List)
{
	//没有节点
	if (NULL ==P_List->P_Head&&NULL == P_List->P_Tail)
	{
		//直接返回
		return;
	}
	else if (P_List->P_Head == P_List->P_Tail)
	{
		//只有一个节点
		printf("%p\t%p\t%p\t%d\n", P_List->P_Head, P_List->P_Head->P_Pre, P_List->P_Head->P_Next, P_List->P_Head->Data);
	}
	else
	{
		//头节点
		Node* P_Bak = P_List->P_Tail;
		while (P_Bak!=P_List->P_Head)
		{
			printf("%p\t%p\t%p\t%d\n", P_Bak,P_Bak->P_Pre, P_Bak->P_Next, P_Bak->Data);
			P_Bak = P_Bak->P_Pre;
		}
		//补充最后一次打印
		printf("%p\t%p\t%p\t%d\n", P_Bak, P_Bak->P_Pre, P_Bak->P_Next, P_Bak->Data);
		
	}
}

//尾部添加节点
void PushBack(A_DoubleList* P_List, DataType Data)
{
	//创建一个新节点
	Node* P_New = (Node*)malloc(sizeof(Node));

	//初始化节点
	InitNode(P_New, Data);

	
	if (P_List->P_Head == NULL && P_List->P_Tail == NULL)
	{
		//如果没有节点的情况

		//前驱和后继都一样
		P_List->P_Head=P_List->P_Tail=P_New;
		P_New->P_Next = P_New->P_Pre = P_New;
	}
	else
	{


		//如果已有一个节点
		if (P_List->P_Head == P_List->P_Tail)
		{
			//修改新节点的前驱和后继
			P_List->P_Head->P_Pre = P_List->P_Head->P_Next = P_New;
			//修改新节点的前驱和后继
			P_New->P_Pre = P_New->P_Next = P_List->P_Head;
			//修改尾部节点的指向
			P_List->P_Tail = P_New;
		}
		else
		{

			//修改尾部节点后继
			P_List->P_Tail->P_Next = P_New;
			//修改新结点的前驱
			P_New->P_Pre = P_List->P_Tail;
			//修改新节点的后继
			P_New->P_Next = P_List->P_Head;
			//重新定尾部指针
			P_List->P_Tail = P_New;
			//修改头指针指向的前驱
			P_List->P_Head->P_Pre = P_List->P_Tail;
			
		}

	}
}

//头部添加节点
void PushHead(A_DoubleList* P_List, DataType Data)
{
	//创建一个新节点
	Node* P_New = (Node*)malloc(sizeof(Node));

	//初始化节点
	InitNode(P_New, Data);

	//如果没有节点的情况
	if (P_List->P_Head == NULL && P_List->P_Tail == NULL)
	{
		//头尾节点指针一样
		P_List->P_Head = P_List->P_Tail = P_New;
		//新节点的前驱和后继一样
		P_New->P_Next = P_New->P_Pre = P_New;
	}
	else
	{
		//新节点的后继
		P_New->P_Next =P_List->P_Head;
		//新节点的前驱
		P_New->P_Pre = P_List->P_Tail;
		//头节点的前驱
		P_List->P_Head->P_Pre = P_New;
		//重新定义新的头节点指针
		P_List->P_Head = P_New;
		//重新定义新的尾节点后继
		P_List->P_Tail->P_Next =P_List->P_Head;
		
	}
}

//查找指定节点
Node* FindNode(A_DoubleList* P_List, DataType Data)
{
	//如果没有节点,那还找个毛。
	if (NULL == P_List->P_Head&&NULL == P_List->P_Tail)
	{
		return NULL;
	}
	
	//备份头节点
	Node* P_Bak =P_List->P_Head;
	while (P_Bak->P_Next!=P_List->P_Head)
	{
		//穷举
		if (P_Bak->Data == Data)
		{
			return P_Bak;
		}
		P_Bak = P_Bak->P_Next;
	}

	return P_Bak->Data == Data ? P_Bak :NULL;
}

//将节点插入指定位置
void InsertNode(A_DoubleList* P_List, DataType Rear, DataType InsData)
{
	//插入之前先查找
	Node* P_Res = FindNode(P_List, Rear);

	//如果“P_Res”等于“NULL”说明没有找到
	if (NULL == P_Res)
	{
		//直接返回
		return;
	}
	else
	{
		//创建一个节点
		Node* P_New = (Node*)malloc(sizeof(Node));
		//初始化节点
		InitNode(P_New, InsData);

		
		if (P_Res == P_List->P_Head)
		{
			//如果“P_Res”等于头节点

			if (P_List->P_Head == P_List->P_Tail)
			{
				//只有一个节点的情况

				//修改头指针指向的前驱和后继
				P_List->P_Head->P_Pre = P_List->P_Head->P_Next = P_New;
				//修改新节点的前驱和后继
				P_New->P_Pre = P_New->P_Next = P_List->P_Head;
				//修改尾指针指
				P_List->P_Tail = P_New;
			}
			else
			{
				//有多个节点的情况

				//修改新节点的前驱
				P_New->P_Pre = P_List->P_Head;
				//修改新节点的后继
				P_New->P_Next = P_List->P_Head->P_Next;
				//修改第二个节点的前驱
				P_List->P_Head->P_Next->P_Pre = P_New;
				//修改头指针指向的后继				
				P_List->P_Head->P_Next = P_New;
			}

		}
		else if (P_Res != P_List->P_Head&&P_Res != P_List->P_Tail)
		{
			//如果“P_Res”在“P_List->P_Head”和“P_List->P_Tail”之间

			//修改新节点的前驱
			P_New->P_Pre = P_Res;
			//修改新节点的后继
			P_New->P_Next = P_Res->P_Next;
			//修改“P_Res->P_Next->P_Pre”的前驱、修改“P_Res”的后继
			P_Res->P_Next->P_Pre= P_Res->P_Next = P_New;
					
		}
		else if(P_Res==P_List->P_Tail)
		{
			//如果“P_Res”等于“P_List->P_Tail”

			//修改新节点的前驱
			P_New->P_Pre = P_List->P_Tail;
			//修改新节点的后继
			P_New->P_Next = P_List->P_Tail->P_Next;
			//修改尾指针指向的后继
			P_List->P_Tail->P_Next = P_New;
			//修改尾部指针的指向
			P_List->P_Tail = P_New;
		}
			   	
	}

}

//修改指定节点的值
void Modification(A_DoubleList* P_List, DataType OldData, DataType NewData)
{
	//修改之前先查找
	Node* P_Res = FindNode(P_List, OldData);

	//如果没有找到,那改个毛
	if (NULL == P_Res)
	{
		return;
	}
	else
	{
		//修改节点对应的数据
		P_Res->Data = NewData;
	}

}

//删除指定节点
void DeleteNode(A_DoubleList* P_List, DataType DelData)
{
	//删除之前先查找

	//保存查找的的节点地址
	Node* P_Res = FindNode(P_List, DelData);


	//如果没有找到那还删除个毛啊
	if (NULL == P_Res)
	{
		//直接返回
		return;
	}
	else
	{
		
		if (P_Res == P_List->P_Head)
		{
			//如果“P_Res”等于头节点

			if (P_List->P_Head == P_List->P_Tail)
			{
				//如果只有一个节点

				//修改头指针指向的前驱和后继
				P_List->P_Head->P_Next = P_List->P_Head->P_Pre = NULL;
				//修稿节点对应的数据
				P_List->P_Head->Data = 0;
				//修改头指针和尾指针的指向
				P_List->P_Head = P_List->P_Tail = NULL;

			}
			else
			{
				//有多个节点

				//修改头指针指向的后继
				P_List->P_Head = P_List->P_Head->P_Next;
				//修头指针指向的前驱
				P_List->P_Head->P_Pre = P_List->P_Tail;
				//修改尾指针指向的后继
				P_List->P_Tail->P_Next = P_List->P_Head;
			
			}
	
		}
		else 
		{
			
			if (P_Res != P_List->P_Head&&P_Res != P_List->P_Tail)
			{
				//如果“P_Res”在“P_List->P_Head”和“P_List->P_Tail”之间	

				//修改“P_Res”上一个节点的后继
				P_Res->P_Pre->P_Next = P_Res->P_Next;
				//修改“P_Res”下一个节点的前驱
				P_Res->P_Next->P_Pre = P_Res->P_Pre;

			
			}
			else
			{
				//有两个节点的情况
				if (P_List->P_Head->P_Next == P_List->P_Head->P_Pre&&P_List->P_Tail->P_Next == P_List->P_Tail->P_Pre)
				{
					//删除节点
					P_List->P_Tail = P_List->P_Tail->P_Pre;
					
				}
				else
				{
					//修改尾部指针的指向
					P_List->P_Tail = P_List->P_Tail->P_Pre;
					//修改尾部指针的后继
					P_List->P_Tail->P_Next = P_List->P_Head;
					//修改头部指针的前驱
					P_List->P_Head->P_Pre = P_List->P_Tail;
				}
			}		
		}	

		//初始化节点
		P_Res->Data = 0;
		P_Res->P_Next = P_Res->P_Pre = NULL;
		//释放内存
		free(P_Res);
		//避免野指针
		P_Res = NULL;
	}		
}

//销毁链表
void Destory(A_DoubleList* P_List)
{	
	//循环删除
	while (NULL != P_List->P_Tail)
	{
		DeleteNode(P_List, P_List->P_Head->Data);
	}
}

猜你喜欢

转载自blog.csdn.net/baidu_41905806/article/details/85114634