数据结构与算法(单循环链表)

    单循环链表实际上只是在单链表的基础上,多加了个尾指针的概念,将尾结点的指针指向头结点,构成一个单循环,难度并不难。许多功能跟单循环都是一样的,不解释,上代码。


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

int Sdata;		//链表数据数量

#define LEN sizeof(struct listdata)

typedef struct listdata
{
	int data;
	struct listdata *next;
}node;

node* Ilist()	/* 初始化链表 */
{
	node *head;		//头指针
	node *temp,*tail;		//中间指针,尾指针
	int data;

	head = NULL;
	printf("请输入数据,输入0为结束\n");
	while(1)
	{
		scanf("%d",&data);
		fflush(stdin);

		if(data == 0)
		{
			printf("退出初始化···\n");
			goto end;
		}

		if(head == NULL)		
		{
			head = (node*)malloc(LEN);
			if(!head)
			{
				printf("内存分配失败,退出程序···\n");
				exit(0);
			}
			head->data = data;
			head->next = head;
			Sdata++;
		}
		else
		{
			for(temp = head;temp->next != head;temp = temp->next)
			{
				;
			}
			tail = (node*)malloc(LEN);
			if(!tail)
			{
				printf("内存分配失败,退出程序···\n");
				exit(0);
			}
			tail->data = data;
			temp->next = tail;
			tail->next = head;
			Sdata++;
		}
	}

end:return head;
}

void Plist(node *L)		/*打印链表*/
{
	int i = 0;
	node *P;
	if(L == NULL)
	{
		printf("此链表为空!\n");
		return;
	}

	for(P = L;i != Sdata;i++)
	{
		printf("\t%d",P->data);
		P = P->next;
	}
}

node* Nlist(node *L)
{
	int data,x,i;
	node *P1,*P2;
LOOP:printf("请输入想要插入的数据、位置:");
	scanf("%d %d",&data,&x);

	if(x < 0 || x-1 > Sdata)
	{
		printf("插入的位置有误!\n");
		goto LOOP;
	}

	if(L == NULL)	//空链表,直接插入
	{
		printf("空链表,直接插入\n");
		P1 = (node*)malloc(LEN);
		if(!P1)
		{
			printf("内存分配失败,退出程序···\n");
			exit(0);
		}
		P1->data = data;
		P1->next = L;
		L = P1;
		Sdata++;
		goto END;
	}

	if(x == 1)		//插入位置为第一时
	{
		P1 = (node*)malloc(LEN);
		if(!P1)
		{
			printf("内存分配失败,退出程序···\n");
			exit(0);
		}

		P1->data = data;

		for(P2 = L;P2->next != L;P2 = P2->next)		//P2此时为尾指针
		{
			;
		}

		P1->next = L;
		P2->next = P1;
		L = P1;
		Sdata++;
	}
	else
	{
		P1 = L;
		for(i = 1;i < (x-1);i++)//P1指向即将插入的前一个位置
		{
			P1 = P1->next;
		}

		P2 = (node*)malloc(LEN);
		if(!P2)
		{
			printf("内存分配失败\n");
			exit(0);
		}

		P2->data = data;
		P2->next = P1->next;
		P1->next = P2;
		Sdata++;
	}
END:return L;
}

node* Dlist(node* L)	/*删除结点*/
{
	node *P1,*P2;
	int x;
	int i;
LOOP:printf("请输入删除结点的位置:");
	scanf("%d",&x);

	if(L == NULL)
	{
		printf("空链表,无法进行此操作\n");
		return L;
	}
	
	if(x < 0 || x > Sdata)
	{
		printf("删除结点的位置有误!\n");
		goto LOOP;
	}

	P1 = P2 = L;
	if(Sdata == 1)
	{
		free(L);
		L = NULL;
		Sdata--;
	}
	else if(x == 1)
	{
		for(;P2->next != L;P2 = P2->next)
		{
			;
		}
		L = L->next;
		P2->next = L;
		free(P1);
		Sdata--;
	}
	else
	{
		for(i = 1;i < (x-1);i++)
		{
			P1 = P1->next;
		}
		P2 = P1->next;
		P1->next = P2->next;
		free(P2);
		Sdata--;
	}
	return L;
}

void main()
{
	node *L;
	int x;
	
	Sdata = 0;	//链表数据记录
	system("color 0A");
	printf("/************************/\n");
	printf("  数据结构: 单循环链表    \n");
	printf("    编写者: H			  \n");
	printf("  欢饮交流: 云客联盟      \n");
	printf("/************************/\n");
	printf("功能选择:                 \n");
	printf("\t0:退出\n \t1:初始化链表\n \t2.打印链表\n \t3.插入结点\n \t4.查看结点数\n \t5.删除结点\n");
	printf("\t6:关于程序\n");
	while(1)
	{
		printf("\n请输入功能:");
		scanf("%d",&x);
		fflush(stdin);

		if(x == 0)
		{
			printf("\n让编程改变世界!\n");
			printf("退出程序···\n");
			exit(0);
		}

		switch(x)
		{
			
			case 1:L = Ilist();
				   break;

			case 2:Plist(L);
			       break;

			case 3:L = Nlist(L);
				   break;

			case 4:printf("此时单循环链表的结点数为:%d",Sdata);
				   break;

			case 5:L = Dlist(L);
				   break;
			
			case 6:printf("\t单循环链表本质其实只是在单链表上加了尾指针这个概念,\n");
				   printf("\t将尾结点的指针指向头,构成一个单循环,程序难度: ***  \n");
				   printf("\t本程序为防止恶意输入多写了许多检查,另外多了个全局 \n");
				   printf("\t变量,用于存储链表结点数,有一定的作用.              \n");
				   break;

			default:printf("sorry,没有这个选项!\n");
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值