单循环链表的相关操作

单循环链表的相关操作

#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"); 
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

甜不辣-酱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值