《C语言》单链表——增、删、查、改、销毁、排序、翻转、合并、取中间节点...

7 篇文章 0 订阅

《C语言》单链表——增、删、查、改、销毁、排序、翻转、合并、取中间节点...

Main.c

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

#define N 10

void main()
{

/************************尾部添加节点************************/
#if 0
	//创建一个结构体指针(32Bit-占四字节)
	SingleList* P_Head = NULL;

	for(int i=0;i<N;i++)
	{
		//尾部添加节点
		PushBack(&P_Head, i);
	}
	//显示节点
	Show(P_Head);
#endif

/************************头部添加节点************************/
#if 0

	//定义一个结构体指针
	SingleList* P_Head = NULL;

	for (int i = 0; i < N; i++)
	{
		//头部添加节点
		PushHead(&P_Head, i);
	}

	//显示链表状态
	Show(P_Head);
#endif

/************************查找指定节点************************/
#if 0

	//定义一个结构体指针
	SingleList* P_Head = NULL;

	//循环插入节点
	for (int i = 0; i < N; i++)
	{
		PushBack(&P_Head, i);
	}

	//显示链表状态
	Show(P_Head);

	//查找节点,分别查找“0”、“5”、“9”
	//如果有一个找不到就打印“Can't found!”
	if (NULL != FindNode(P_Head, 0) && NULL != FindNode(P_Head, 5) && NULL != FindNode(P_Head, 9))
	{
		puts("Find");
	}
	else
	{
		puts("Can't found!");
	}

#endif

/************************将节点插入指定位置************************/
#if 0
	//定义结构体指针
	SingleList* P_Head = NULL;
	
	//循环添加节点
	for (int i = 0; i < N; i++)
	{
		//尾部添加节点
		PushBack(&P_Head, i);
	}

	//显示链表状态(插入节点之前)
	Show(P_Head);


	InsertNode(&P_Head, 0, 100);

	InsertNode(&P_Head, 5, 100);

	InsertNode(&P_Head, 9, 100);

	//显示链表状态(插入节点之后)
	Show(P_Head);
#endif

/************************删除指定节点************************/
#if 0
	//定义结构体指针
	SingleList* P_Head = NULL;

	//循环添加节点
	for (int i = 0; i < N; i++)
	{
		//尾部添加节点
		PushBack(&P_Head, i);
	}

	//显示链表状态(插入节点之前)
	Show(P_Head);

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

	Show(P_Head);
#endif

/************************统计链表节点************************/
#if 0
		//定义结构体指针
	SingleList* P_Head = NULL;

	//循环添加节点
	for (int i = 0; i < N*N; i++)
	{
		//尾部添加节点
		PushBack(&P_Head, i);
	}

	//显示链表状态(插入节点之前)
	Show(P_Head);
	printf("该链表合计\t%u\t个节点\n", CounterNode(P_Head));
#endif

/************************修改链表节点************************/
#if 0

			//定义结构体指针
	SingleList* P_Head = NULL;

	//循环添加节点
	for (int i = 0; i < N; i++)
	{
		//尾部添加节点
		PushBack(&P_Head, i);
	}

	//显示链表状态(插入节点之前)
	Show(P_Head);
	
	Modification(P_Head, 0, 100);
	Modification(P_Head, 5, 100);
	Modification(P_Head, 9, 100);

	Show(P_Head);
#endif

/************************获取链表的中间节点************************/
#if 0
		//定义结构体指针
	SingleList* P_Head = NULL;

	//循环添加节点
	for (int i = 0; i < N; i++)
	{
		//尾部添加节点
		PushBack(&P_Head, i);
	}

	//显示链表状态(插入节点之前)
	Show(P_Head);

	printf("中间节点:%d\n",(GetMiddleNode(P_Head))->Data);
#endif

/************************链表合并************************/	
#if 0

	SingleList* P_All=NULL;
	SingleList* P_Head1 = NULL;
	SingleList* P_Head2 = NULL;

	for (int i = 0; i <10; i++)
	{
		
		if (i % 2)
		{
			PushBack(&P_Head2, i);
		}
		else
		{
			PushBack(&P_Head1, i);
		}
	}

	Show(P_Head1);
	Show(P_Head2);

	Merge(&P_All, P_Head1, P_Head2);
	Show(P_All);
#endif

/************************销毁链表************************/
#if 0
		//定义结构体指针
	SingleList* P_Head = NULL;

	//循环添加节点
	for (int i = 0; i < N; i++)
	{
		//尾部添加节点
		PushBack(&P_Head, i);
	}

	//显示链表状态(插入节点之前)
	Show(P_Head);

	Destory(&P_Head);

	Show(P_Head);
#endif

/************************链表反转(循环)************************/
#if 0
		//定义结构体指针
	SingleList* P_Head = NULL;

	//循环添加节点
	for (int i = 0; i < N; i++)
	{
		//尾部添加节点
		PushBack(&P_Head, i);
	}

	//显示链表状态(插入节点之前)
	Show(P_Head);
	ReversalByLoop(&P_Head);
	Show(P_Head);
#endif


/************************链表反转(递归)************************/
#if 0
		//定义结构体指针
	SingleList* P_Head = NULL;

	//循环添加节点
	for (int i = 0; i < N; i++)
	{
		//尾部添加节点
		PushBack(&P_Head, i);
	}

	//显示链表状态(插入节点之前)
	Show(P_Head);
	P_Head= ReversalByRecursion(P_Head);
	Show(P_Head);
#endif

/************************冒泡排序************************/
#if 0

	//获取随机数种子
	srand((unsigned int)time(NULL));

	//定义结构体指针
	SingleList* P_Head = NULL;
	
	//循环添加节点
	for (int i = 0; i < N; i++)
	{
		//尾部添加节点
		PushBack(&P_Head, rand()%100);
	}
	//显示链表状态
	Show(P_Head);
	BubbleSort(P_Head);
	Show(P_Head);
#endif

/************************快速排序************************/
#if 0
 

	//获取随机数种子
	srand((unsigned int)time(NULL));

	//定义结构体指针
	SingleList* P_Head = NULL;

	//循环添加节点
	for (int i = 0; i < N; i++)
	{
		//尾部添加节点
		PushBack(&P_Head, rand() % 100);
	}
	//显示链表状态
	Show(P_Head);
	QuickSort(P_Head,NULL);
	Show(P_Head);
#endif


/************************选择排序************************/
#if 1

	//获取随机数种子
	srand((unsigned int)time(NULL));

	//定义结构体指针
	SingleList* P_Head = NULL;

	//循环添加节点
	for (int i = 0; i < N; i++)
	{
		//尾部添加节点
		PushBack(&P_Head, rand() % 100);
	}

	//显示链表状态
	Show(P_Head);
	SelectSort(P_Head);
	Show(P_Head);
#endif
	system("pause");
}

SingleList.h

#pragma once 


#ifdef __cplusplus
extern"C"
{
#endif

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

	typedef int DataType;

	typedef struct SingleList
	{
		DataType Data;
		struct SingleList* P_Next;
	}SingleList;



	//显示链表状态
	void Show(SingleList* P_Head);
	//初始化节点
	void InitNode(SingleList* P_Node, DataType Data);
	//数据交换
	void Swap(SingleList* Pa, SingleList*  Pb);
	//链表分段
	SingleList* Segmentaction(SingleList* P_Begin, SingleList* P_End);
	
	//尾部追加节点
	void PushBack(SingleList** PP_Head, DataType Data);
	//头部添加节点
	void PushHead(SingleList** PP_Head,DataType Data);
	//查找指定节点
	SingleList* FindNode(SingleList* P_Head, DataType FindData);
	//将节点插入指定位置
	void InsertNode(SingleList** PP_Head, DataType Rear, DataType InsData);
	//删除指定节点
	void DeleteNode(SingleList** PP_Head, DataType Data);
	//修改链表节点
	void Modification(SingleList* P_Head, DataType OldData, DataType NewData);
	//统计链表节点
	unsigned int CounterNode(SingleList*P_Head);
	//获取链表的中间节点
	SingleList* GetMiddleNode(SingleList* P_Head);
	//链表合并
	void Merge(SingleList** PP_ALL, SingleList* P_Head1, SingleList* P_Head2);
	//销毁链表
	void Destory(SingleList** PP_Head);
	//链表反转(循环)
	void ReversalByLoop(SingleList** PP_Head);
	//链表反转 (递归)
	SingleList* ReversalByRecursion(SingleList* P_Head);
	//冒泡排序
	void BubbleSort(SingleList* P_Head);
	//快速排序
	void QuickSort(SingleList* P_Begin, SingleList* P_End);
	//选择排序
	void SelectSort(SingleList* P_Head);
#ifdef __cplusplus
}
#endif

SingleList.c

#include "SingleList.h"



//显示链表状态
void Show(SingleList* P_Head)
{
	//如果“P_Head”为空就直接跳出
	if (NULL == P_Head)
	{
		puts("");
		return;
	}
	else
	{
		//顺序打印
		printf("%p\t%p\t%d\n",P_Head,P_Head->P_Next,P_Head->Data);
		Show(P_Head->P_Next);
		//逆序打印
		//printf("%p\t%p\t%d\n", P_Head, P_Head->P_Next, P_Head->Data);
	}

}

//初始化节点
void InitNode(SingleList* P_Node, DataType Data)
{
	//下一个节点为空
	P_Node->P_Next = NULL;
	//初始化该节点的“Data”
	P_Node->Data = Data;
}

//数据交换
void Swap(SingleList* Pa, SingleList*  Pb)
{
	DataType Temp = Pa->Data;
	Pa->Data = Pb->Data;
	Pb->Data = Temp;
}

//链表分段
SingleList* Segmentaction(SingleList* P_Begin, SingleList* P_End)
{
	//备份数据
	DataType Key = P_Begin->Data;
	//起始点
	SingleList* Pi = P_Begin;

	for (SingleList* Pj = Pi->P_Next; Pj != P_End; Pj = Pj->P_Next)
	{
		if (Key < Pj->Data)
		{
			Pi = Pi->P_Next;
			Swap(Pi, Pj);
		}
	}

	//交换中间节点,让左边的小于“Key”右边的大于“Key”
	Swap(Pi, P_Begin);

	return Pi;
}


//尾部追加节点
void PushBack(SingleList** PP_Head, DataType Data)
{
	//如果头节点为空
	if (NULL == *PP_Head)
	{
		//创建一个节点
		SingleList* P_New=(SingleList*)malloc(sizeof(SingleList));
		//初始化节点
		InitNode(P_New, Data);
		//直接让“*PP_Head”指向“P_New”
		*PP_Head = P_New;
	}
	else
	{
		//头节点不为空

		//创建节点
		SingleList* P_New = (SingleList*)malloc(sizeof(SingleList));
		InitNode(P_New, Data);

		//备份头节点
		SingleList* P_Bak = *PP_Head;
		
		//因为要将最后一个节点指向新的节点,所以要循环
		//到倒数第二个节点
		while (NULL != P_Bak->P_Next)
		{
			P_Bak = P_Bak->P_Next;
		}

		P_Bak->P_Next = P_New;
	}
}
//头部添加节点
void PushHead(SingleList** PP_Head, DataType Data)
{
	//如果头节点为空
	if (NULL == *PP_Head)
	{
		//创建一个新的节点
		SingleList* P_New = (SingleList*)malloc(sizeof(SingleList));

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

		//直接让“*PP_Head”指向“P_New”
		*PP_Head = P_New;
	}
	else
	{
		//头节点不为空

		//创建一个新节点
		SingleList* P_New = (SingleList*)malloc(sizeof(SingleList));
		//初始化新节点
		InitNode(P_New, Data);

		//直接让“P_New->PNext”指向头节点
		P_New->P_Next = *PP_Head;

		//重新定义头节点,让“*PP_Head”指向“P_New”
		*PP_Head = P_New;
	}
}

//查找指定节点
SingleList* FindNode(SingleList* P_Head, DataType FindData)
{
	//循环遍历节点
	while (NULL != P_Head)
	{
		//穷举
		if (FindData == P_Head->Data)
		{
			//返回相对应的节点地址
			return P_Head;
		}
		P_Head = P_Head->P_Next;
	}
	//如果没有找到返回“NULL”
	return NULL;
}

//将节点插入指定位置
void InsertNode(SingleList** PP_Head, DataType Rear, DataType InsData)
{
	//插入之前先查找该该节点是否存在
	SingleList* P_Res = FindNode(*PP_Head, Rear);

	//如何没找到,那还插个毛啊 -_-|||
	if (NULL == P_Res)
	{
		return;
	}
	else
	{
		//如果找到了就创建一个节点先
		SingleList* P_New = (SingleList*)malloc(sizeof(SingleList));
		//初始化节点
		InitNode(P_New, InsData);
		
		 if(NULL == P_Res->P_Next)	
		{
			//如果“P_Res->P_Next==NULL”说明“P_Res”在倒数
			//第二个节点

			//让“P_Res->P_Nex”指向“P_New”
			P_Res->P_Next = P_New;
		}
		else 
		{
	
			P_New->P_Next = P_Res->P_Next;
			P_Res->P_Next = P_New;
		}
		
	}

}

//删除指定节点
void DeleteNode(SingleList** PP_Head, DataType Data)
{
	//删除之前先查找
	SingleList* P_Res = FindNode(*PP_Head, Data);

	//如果没有找到,那还删个毛啊
	if (NULL == P_Res)
	{
		return;
	}
	else
	{
	
		if (P_Res == *PP_Head)
		{
			//如果“P_Res”等于“*PP_Head”

			//让头节点指向下一个节点
			*PP_Head = (*PP_Head)->P_Next;

			//释放内存
			free(P_Res);
			//避免野指针
			P_Res = NULL;
		}
		
		else
		{
			//当“P_Res”在首尾节点之间

			//循环到“P_Res”的上一个节点
			//备份头指针
			SingleList* P_Bak = *PP_Head;

			while (P_Bak->P_Next!=P_Res)
			{
				//趋于终止
				P_Bak = P_Bak->P_Next;
			}

			//删除节点
			P_Bak->P_Next = P_Res->P_Next;

			//释放内存
			free(P_Res);
			//避免野指针
			P_Res = NULL;
		}
	}
}

//修改链表节点
void Modification(SingleList* P_Head, DataType OldData, DataType NewData)
{
	//修改之前先查找
	SingleList* P_Res = FindNode(P_Head,OldData);
	
	//如果没找到,那还改个毛啊-_-|||
	if (NULL == P_Res)
	{
		//直接返回
		return;
	}
	else
	{
		P_Res->Data = NewData;
	}

}

//统计链表节点
unsigned int CounterNode(SingleList*P_Head)
{
	if (NULL == P_Head)
	{
		return 0;
	}
	return 1 + CounterNode(P_Head->P_Next);
}

//获取链表的中间节点
SingleList* GetMiddleNode(SingleList* P_Head)
{
	//当头节点为空或者只有一个节点的情况
	if (NULL == P_Head || NULL == P_Head->P_Next)
	{
		//直接返回
		return P_Head;
	}
	
	SingleList* Pi=P_Head;
	SingleList* Pj=P_Head;

	while (NULL != Pi->P_Next)
	{
		Pi = Pi->P_Next;
		Pj = Pj->P_Next;

		if (NULL != Pi->P_Next)
		{
			Pi = Pi->P_Next;
		}
	}
	return Pj;
}

//链表合并
void Merge(SingleList** PP_ALL, SingleList* P_Head1, SingleList* P_Head2)
{

	while (NULL != P_Head1 || NULL != P_Head2)
	{
		if (NULL != P_Head1 && NULL != P_Head2)
		{
			//对比数据大小,插入合适的位置
			if (P_Head1->Data < P_Head2->Data)
			{
				PushBack(PP_ALL, P_Head1->Data);
				P_Head1 = P_Head1->P_Next;
			}
			else
			{
				PushBack(PP_ALL, P_Head2->Data);
				P_Head2 = P_Head2->P_Next;
			}		
		}
		else
		{
			//循环添加节点
			while (NULL != P_Head1)
			{
				PushBack(PP_ALL, P_Head1->Data);
				P_Head1 = P_Head1->P_Next;
			}

			//循环添加节点
			while (NULL != P_Head1)
			{
				PushBack(PP_ALL, P_Head2->Data);
				P_Head2 = P_Head2->P_Next;
			}
			break;
		}
	}
}

//销毁链表
void Destory(SingleList** PP_Head)
{

	while (*PP_Head != NULL)
	{
		SingleList* Pi = *PP_Head;
		*PP_Head = (*PP_Head)->P_Next;

		if (NULL == *PP_Head)
		{
			break;
		}

		//释放内存
		free(Pi);
		//避免野指针
		Pi = NULL;
	}
}

//链表反转(循环)
void ReversalByLoop(SingleList** PP_Head)
{
	//如果头指针为空或者只有一个节点
	if (NULL == *PP_Head || NULL == (*PP_Head)->P_Next)
	{
		return;
	}
	else
	{
		//上一个指针,中间节点,下一个节点
		SingleList* P_Pre, *P_Cur, *P_Next;
		P_Pre=P_Cur=P_Next= NULL;

		//保存头指针
		P_Pre = *PP_Head;
		//保存下一节点
		P_Cur = (*PP_Head)->P_Next;
		while (NULL != P_Cur)
		{
			//轮替
			P_Next = P_Cur->P_Next;
			P_Cur->P_Next = P_Pre;
			P_Pre = P_Cur;
			P_Cur = P_Next;
		}
		
		//尾部为空
		(*PP_Head)->P_Next= NULL;
		//定义新的头节点
		*PP_Head = P_Pre;
	}
}

//链表反转 (递归)
SingleList* ReversalByRecursion(SingleList* P_Head)
{
	//如果头指针为空或者只有一个节点
	if (NULL == P_Head || NULL == P_Head->P_Next)
	{
		return P_Head;
	}
	else
	{
		//保存第二个节点的地址
		SingleList* P_Next = P_Head->P_Next;
		//递归调用
		SingleList* P_NewHead = ReversalByRecursion(P_Next);

		P_Next->P_Next = P_Head;
		P_Head->P_Next = NULL;

		//返回新的头节点地址
		return P_NewHead;
	}
}
//冒泡排序
void BubbleSort(SingleList* P_Head)
{
	for (SingleList* Pi = P_Head; NULL != Pi; Pi = Pi->P_Next)
	{
		//每冒泡一次就有一个极值沉底
		for (SingleList* Pj = Pi->P_Next; NULL != Pj; Pj = Pj->P_Next)
		{
			if (Pi->Data < Pj->Data)
			{
				//数据交换
				Swap(Pi,Pj);
			}
		}
			
	}
}

//快速排序
void QuickSort(SingleList* P_Begin, SingleList* P_End)
{
	if (P_Begin != P_End)
	{
		SingleList* Pi = Segmentaction(P_Begin, P_End);
		//分割左边
		QuickSort(P_Begin, Pi);
		//分割右边
		QuickSort(Pi->P_Next, P_End);
	}

}

//选择排序
void SelectSort(SingleList* P_Head)
{
	//保存极值的节点地址
	SingleList* P_Limit = NULL;

	for (SingleList* Pi = P_Head; NULL != Pi; Pi = Pi->P_Next)
	{
		//假设“Pi”为极值的节点
		P_Limit = Pi;
		for (SingleList* Pj = Pi->P_Next; NULL != Pj; Pj = Pj->P_Next)
		{
			if (P_Limit->Data < Pj->Data)
			{
				//如果“P_Limit->Data < Pj->Data”就让“P_Limit”保存“Pj”的地址
				P_Limit = Pj;
				P_Limit = Pj;
			}
		}
		//如果“P_Limit”不等于“Pi”,说明“P_Limit”已经存储了其他极值
		//交换数据
		Swap(P_Limit, Pi);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值