天天看點

單循環連結清單的相關操作

單循環連結清單的相關操作

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
typedef struct LinkListNode
{
	int data;
	struct LinkListNode* next;
}node,*LinkList;  //結構體變量類型

void  GreatLinklistTail(LinkList* head); // 建立連結清單
void LinkListInsert(LinkList* head); //插入節點
void LinkListFind(LinkList* head); //查找資料 
void LinkListnode_Delete(LinkList* head); //删除節點
void LinkListDatePrint(LinkList* head);  //連結清單的輸出
void LinkListClean(LinkList* head);   //連結清單的整表删除 
/**
*為了建立、使用、維護連結清單,對連結清單的操作如下:
*建立連結清單
*周遊連結清單
*尾部追加
*删除結點
*查找結點
*/
/******************************************************************************/
int main(void)
{
	LinkList head;
	int i;
	printf("*************************單循環連結清單操作***************************\n\n");
	printf("1.初始化循環連結清單\n\n2.插入節點 \n\n3.删除節點 \n\n4,查找節點\n\n0.釋放記憶體操作完成\n\n"); 
	while(1)
	{
		scanf("%d", &i);
		switch(i)
		{
		
			case 1:
				{
					printf("下面進行建立連結清單操作!\n"); 
					GreatLinklistTail(&head);
					LinkListDatePrint(&head);
				}
				break;
			case 2:
				{
					printf("下面進行插入節點操作!\n"); 
					LinkListInsert(&head);
					LinkListDatePrint(&head);
				}
				break;
			case 3:
				{ 
				printf("下面進行删除節點操作!\n"); 
				LinkListnode_Delete(&head);
				LinkListDatePrint(&head);
				} 
				break;
			case 4:
				{
					printf("下面進行查找資料操作!\n"); 
					LinkListFind(&head);
				} 
				break;
			
		}
		if(i == 0)
		{
			break;
		}
	}
	printf("連結清單操作結束!\n"); 
	LinkListClean(&head);
	system("pause"); 
	return 0;
}
/**********************************************************************************/

//單循環連結清單初始化操作 
void GreatLinklistTail(LinkList* head)
{
	node *p, *target = NULL;   //聲明節點p 和周遊結構體指針變量 target 
	int i, j;
 
	*head = (LinkList)malloc(sizeof(LinkList)); //為第一個節點開辟記憶體 
	(*head)->next = *head;  //将第一個指針的next 指向第一個節點 
	target = *head;    //令周遊指針 指向第一個節點 
	printf("請輸入所要開辟節點的個數,輸入0退出: \n");
	scanf_s("%d", &i);
	fflush(stdin);

	if(i == 0)
	{
		return ;  //如果輸入 0直接退出程式 
	}
	
	 
	if (i == 1)//當隻要開辟一個節點的時候  令第一個節點的next指向自身形成循環連結清單 
	{
		printf("請輸入要存儲的值:");
		scanf_s("%d", &(*head)->data);
		fflush(stdin);
		
		(*head)->next = *head; //令第一個節點的next指向自身形成循環連結清單 
		printf("單循環連結清單建立完畢!!!\n\n");
	}
	
	else
	{	
		for (j = 1; j <= i; j++)
		{
			
			if(j == 1)  //開辟第一個節點時 
			{	
				printf("請輸入第%d個節點所要存儲的資料:", j);
				p = *head;  //令p指向第一個節點 便于操作 
				scanf_s("%d", &p->data); 
				p->next = p;  //令第一個節點的next指向 自身 
			}
			else  //第一個節點建立結束後 
			{
				p = (node*)malloc(sizeof(node));  //為新節點開辟節點 
				if (!p)
				{
					exit(0);  //配置設定記憶體失敗退出  
				}
				
				printf("請輸入第%d個節點所要存儲的資料:", j);
				scanf_s("%d", &p->data);
	
				p->next = target->next; //先後繼再前驅原則,令p的next指向第一結點 
				target->next = p; //将上一個節點的next 指向p 
				target = p; //周遊節點向後移位 
			}
		}
	}
	printf("單連結清單建立完畢!!!\n\n");
} 

//列印資料函數 
//連結清單資料的輸出 
/*思路:
	1,開辟一個節點p
	2,令節點p指向第一個節點
	3,通過循環列印出每個節點的值
*/
void LinkListDatePrint(LinkList *head)    //輸出循環連結清單的所有元素 
{
	node *p;  
	int j = 1;
	p = *head;
	printf("********************連結清單中的資料********************\n"); 
	do   // 不可用 當型循環 
	{
		printf("第%d個節點存儲的數為:%4d;\n", j , p->data);
		p = p->next;  //循環周遊連結清單算法 
		j++;
	}while(p != *head);  //周遊到最後一個節點為止 
	
	printf("連結清單資料列印完畢!!!\n\n");
}

//連結清單的整表删除
/*思路:
	1,聲明節點p,q
	2,将第一個節點賦給p,下一個賦給 q
	3,循環執行釋放p和将q賦給p操作
*/
void LinkListClean(LinkList* head)
{
	node* p, * q;

	p = *head;
	while (p->next != (*head))  //循環釋放法則 
	{
		q = p->next;
		free(p);
		p = q;
	}  
	printf("單連結清單記憶體釋放成功!!!\n");
}

//連結清單的資料插入操作

void LinkListInsert(LinkList* head) //插入節點
{
	node *p, *s;  //聲明循環周遊結構體指針p 和 插入節點 s 
	int i, j = 1;

	s = (node*)malloc(sizeof(node));  //為要插入的節點開辟記憶體  
	
	s->next = NULL;  //防止成為野指針
	p = *head;  //令循環節點指向頭結點 
	
	printf("請輸入要插入的節點的位置:");
	scanf_s("%d", &i);
	fflush(stdin);

	if (i == 1)
	{
		printf("請輸入第%d個節點要插入的值:\n", i);
		scanf_s("%d", &s->data);  //指派操作  
		fflush(stdin);
		
	for(p = *head; p->next != *head; p= p->next)
		;  //尋找最後一個節點 
	
		s->next = *head;  //先後繼 
		p->next = s;  //尾節點指向s  後前驅  算法 
		*head = s;   //把head 再次換成第一個節點 
	}
	else
	{	
		for (j = 1; j < i-1; j++)
		{
			p = p->next; 将循環指針指向 要插入的前一個節點 
		}

		printf("請輸入第%d個節點要插入的值:\n", i);
		scanf_s("%d", &s->data);
		fflush(stdin);

		s->next = p->next;//令插入的節點的next指向原本的第 i個節點 //先後繼 
		p->next = s;  //後前驅 
		printf("\n");
	}
	printf("節點插入成功!!!\n\n"); 
}
//節點的查找并傳回節點的位置 
/*
思路:
	1,聲明節點 p,開辟節點,指向頭結點
	2, 聲明計數器j 和存儲資料的 容器
	3, 循環查找
*/
void LinkListFind(LinkList* head)  //查找第i個元素
{
	node *target;
	int  i, j = 1;

	printf("請輸入查找的資料:");
	scanf_s("%d", &i);
	fflush(stdin);

	for (target = *head; target->data != i && target->next != *head; target = target->next)
		j++;  //循環周遊尋找最後一個節點 
	printf("該節點的位置是: %d\n\n", j);
}

//單連結清單節點删除操作
void LinkListnode_Delete(LinkList* head)
{
	node *p, *target = NULL;  //聲明節點p指向連結清單的第一個節點
	int i;   //要删除的節點 
	int j = 1; //聲明一個計數器  
	p = *head;  //p節點指向第一個節點 

	printf("請輸入要删除的節點标号:");
	scanf_s("%d", &i);
	fflush(stdin);

	if (i == 1)
	{
		for (target = *head; target->next != (*head); target = target->next)
			;  //循環周遊尋找最後一個節點  
			
		p = *head;
		*head = (*head)->next;
		target->next = *head;
		 
		free(p);
	}
	else
	{
		target = *head;
		for (; j < i - 1; j++)  //尋找要删除節點的前一位 
		{
			target = target->next;
		}
		
		p = target->next;  //将p 指向要删除的節點,  
		target->next = p->next;  //使前一個節點指向後一個節點 
		free(p);
		printf("節點删除成功!!!!\n\n"); 
	}

}

           

繼續閱讀