1. 程式人生 > >《C語言》環形連結串列與《約瑟夫問題》

《C語言》環形連結串列與《約瑟夫問題》

環形連結串列與《約瑟夫問題》

Main.c

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


void main()
{
	/********************尾部新增節點********************/
#if 0
	A_List* P_Head = NULL;
	for (int i = 0; i < 10; i++)
	{
		AddBack(&P_Head, i);
	}
	Show(P_Head);
#endif
/********************頭部部新增節點********************/ #if 0 A_List* P_Head = NULL; for (int i = 0; i < 10; i++) { AddHead(&P_Head, i); } Show(P_Head); #endif /********************查詢節點********************/ #if 0 A_List* P_Head = NULL; for (int i = 0; i < 10; i++) { AddHead(&P_Head,
i); } Show(P_Head); if (NULL != FindNode(P_Head, 0) && NULL != FindNode(P_Head, 5) && NULL != FindNode(P_Head, 9)) { puts("Find."); } else { puts("Can't find."); } #endif /********************指定位置插入節點********************/ #if 0 A_List* P_Head = NULL; for (int i = 0; i <
10; i++) { AddHead(&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 A_List* P_Head = NULL; for (int i = 0; i < 10; i++) { AddHead(&P_Head, i); } Show(P_Head); DeleteNode(&P_Head, 0); DeleteNode(&P_Head, 5); DeleteNode(&P_Head, 9); Show(P_Head); #endif /********************修改節點********************/ #if 0 A_List* P_Head = NULL; for (int i = 0; i < 10; i++) { AddHead(&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 A_List* P_Head = NULL; for (int i = 0; i < 10; i++) { AddHead(&P_Head, i); } Show(P_Head); printf("該連結串列有 %u 個節點\n", CountNode(P_Head)); #endif /********************約瑟夫問題********************/ #if 1 A_List* P_Head = NULL; for (int i = 0; i < 100; i++) { AddBack(&P_Head, i); } Show(P_Head); A_List* P_Bak = P_Head; while (CountNode(P_Head) != 1) { for (int i = 0; i < 4; i++) { P_Bak = P_Bak->P_Next; } Joseph(&P_Head,&P_Bak, P_Bak->Data); Show(P_Head); } #endif system("pause"); }

A_List.h

#pragma once 

#ifdef __cplusplus
extern "C"
{
#endif

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

	typedef int DataType;

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

	//初始化節點
	void InitNode(A_List* P_Node);
	//顯示環形連結串列狀態
	void Show(A_List* P_Head);
	//尾部新增節點
	void AddBack(A_List** PP_Head, DataType Data);
	//頭部新增節點
	void AddHead(A_List**PP_Head, DataType Data);
	//查詢節點
	A_List* FindNode(A_List* P_Head,DataType Data);
	//指定位置插入節點
	void InsertNode(A_List** PP_Head, DataType InData, DataType InsData);
	//刪除節點
	void DeleteNode(A_List** PP_Head, DataType DelData);
	//修改節點
	void Modification(A_List* P_Head, DataType OldData, DataType NewData);
	//統計連結串列節點
	unsigned int CountNode(A_List* P_Head);
	//約瑟夫問題
	void Joseph(A_List** PP_Head, A_List** PP_KillNode, DataType KillData);
	

#ifdef __cplusplus
}
#endif

A_List.c

#include "A_List.h"



//初始化節點
void InitNode(A_List* P_Node)
{
	P_Node->P_Next = P_Node;
	P_Node->Data = 0;
}

//顯示環形連結串列狀態
void Show(A_List* P_Head)
{
	if (NULL == P_Head)
	{
		return;
	}
	else if(P_Head==P_Head->P_Next)
	{
		printf("%p\t%p\t%d\n", P_Head, P_Head->P_Next, P_Head->Data);
		puts("");
		return;
	}
	else
	{
		A_List* P_Bak = P_Head;
		while (P_Bak->P_Next!=P_Head)
		{
			printf("%p\t%p\t%d\n", P_Bak, P_Bak->P_Next, P_Bak->Data);
			P_Bak = P_Bak->P_Next;
		}
		printf("%p\t%p\t%d\n", P_Bak, P_Bak->P_Next, P_Bak->Data);
	}
	puts("");
}

//尾部新增節點
void AddBack(A_List** PP_Head, DataType Data)
{
	A_List* P_New = (A_List*)malloc(sizeof(A_List));
	InitNode(P_New);
	P_New->Data = Data;

	if (NULL == *PP_Head)
	{
		*PP_Head = P_New;
		P_New->P_Next = *PP_Head;
	}
	else
	{
		A_List* P_Bak = *PP_Head;
		while (P_Bak->P_Next != *PP_Head)
		{
			P_Bak = P_Bak->P_Next;
		}
		P_Bak->P_Next = P_New;
		P_New->P_Next = *PP_Head;
	}
}

//頭部新增節點
void AddHead(A_List**PP_Head, DataType Data)
{
	A_List* P_New = (A_List*)malloc(sizeof(A_List));
	InitNode(P_New);
	P_New->Data = Data;

	if (NULL == *PP_Head)
	{
		*PP_Head = P_New;
		P_New->P_Next = *PP_Head;
	}
	else
	{
		A_List*P_Bak = *PP_Head;
		while (P_Bak->P_Next !=*PP_Head)
		{
			P_Bak = P_Bak->P_Next;
		}

		P_New->P_Next = *PP_Head;
		*PP_Head = P_New;
		P_Bak->P_Next = *PP_Head;
		
	}
}

//查詢節點
A_List* FindNode(A_List* P_Head,DataType Data)
{
	if (NULL != P_Head)
	{
		if (P_Head == P_Head->P_Next)
		{
			if (P_Head->Data == Data)
			{
				return P_Head;
			}
		}
		else
		{
			A_List* P_Bak = P_Head;
			while (P_Bak->P_Next != P_Head)
			{
				if (P_Bak->Data == Data)
				{
					return P_Bak;
				}
				P_Bak = P_Bak->P_Next;
			}

			if (P_Bak->Data == Data)
			{
				return P_Bak;
			}
		}
	}	
	return NULL;
}

//指定位置插入節點
void InsertNode(A_List** PP_Head, DataType InData, DataType InsData)
{
	if (NULL != *PP_Head)
	{
		A_List* P_Res = FindNode(*PP_Head, InData);
		if (NULL != P_Res)
		{
			A_List* P_New = (A_List*)malloc(sizeof(A_List));
			InitNode(P_New);
			P_New->Data = InsData;

			A_List* P_Bak = P_Res->P_Next;
			P_Res->P_Next = P_New;
			P_New->P_Next = P_Bak;			
		}	
	}
}

//刪除節點
void DeleteNode(A_List** PP_Head, DataType DelData)
{
	if (NULL != *PP_Head)
	{
		A_List* P_Res = FindNode(*PP_Head, DelData);
		if (NULL != P_Res)
		{
			//一個節點的情況
			if ((*PP_Head)->P_Next == *PP_Head)
			{
				free(*PP_Head);
				(*PP_Head)->P_Next = NULL;
				*PP_Head = NULL;
			}
			else
			{
				if (P_Res == *PP_Head)
				{
					A_List* P_Bak = *PP_Head;
					while (P_Bak->P_Next->P_Next!= *PP_Head)
					{
						P_Bak = P_Bak->P_Next;
					}

					P_Bak->P_Next = (*PP_Head)->P_Next;
				
					//指向新的頭節點
					*PP_Head = P_Bak->P_Next;

					free(P_Res);
					P_Res = NULL;
				}
				else
				{
					A_List* 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(A_List* P_Head, DataType OldData, DataType NewData)
{
	if (NULL != P_Head)
	{
		A_List* P_Res = FindNode(P_Head, OldData);
		if (NULL != P_Res)
		{
			P_Res->Data = NewData;
		}
	}
}

//統計連結串列節點
unsigned int CountNode(A_List* P_Head)
{
	if (NULL == P_Head)
	{
		return 0;
	}
	else
	{
		unsigned int i = 0;
		A_List* P_Bak = P_Head;
		while (P_Bak->P_Next != P_Head)
		{
			i++;
			P_Bak = P_Bak->P_Next;
		}

		return ++i;
	}
}

//約瑟夫問題
void Joseph(A_List** PP_Head, A_List** PP_KillNode, DataType KillData)
{
	if (NULL != *PP_Head)
	{
		A_List* P_Res = FindNode(*PP_Head, KillData);
		*PP_KillNode = P_Res->P_Next;
		if (NULL != P_Res)
		{
			if (P_Res == *PP_Head)
			{
				while (P_Res->P_Next != *PP_Head)
				{
					P_Res = P_Res->P_Next;
				}
				P_Res->P_Next = (*PP_Head)->P_Next;

				free(*PP_Head);
				*PP_Head = NULL;

				*PP_Head = P_Res->P_Next;			
			}
			else
			{
				A_List* 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;
			}
		}
	}
}