Linux学习笔记(算法与数据结构)之 环状链表(C语言)

1、这是一道数据结构与算法课程的练习题,题目如下:给定一个数n,建立一个有n个节点的环状链表,第i个节点中存储整数i;给定数start(1<= start <=n)和num,要求从start这个节点开始,每隔num个节点删除一个节点,直到链表为空。

举例:n = 10,start = 2, num = 3

则首先建立环状表,共10个节点,存储整数1、2、3、4、5、6、7、8、9、10

从2开始数3个,2、3、4,所以删除4,删除之后链表为:1、2、3、5、6、7、8、9、10,5代替了原来4的位置

然后从5开始数3个,5、6、7,所以删除7

以此类推

因为当删除第n个节点的时候,需要把第n-1个节点的next值改为第n+1个节点,所以我们查找的时候,直接查找第n-1个节点,然后删除n-1 -> next 即节点n,再将n-1->next->next链接到n-1后端

2、在dev c++下编译通过,都用的c语法,但可能不太严格。

3、本篇博文无注释,命名规则和变量名都和前面链表相关的博文一样。

 

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

typedef struct Node{
	Node *next;
	int data;
} NODE;

typedef struct List{
	NODE *head;
	NODE *tail;
	int size;
} LIST;

void create(LIST *list,int size)
{
	NODE* tmp = (NODE*)malloc(sizeof(NODE));
	tmp->data = 1;
	tmp->next = NULL;
	list->head = tmp;
	list->tail = tmp;
	list->size = 1;
	
	for (int i=2;i<=size;i++)
	{
		tmp = (NODE*)malloc(sizeof(NODE));
		tmp->data = i;
		tmp->next = NULL;
		list->size ++;
		list->tail->next = tmp;
		list->tail = tmp;
	}
	list->tail->next = list->head;
}

void List_Test(LIST *list)
{
	NODE* tmp = list->head;
	while(! (list->tail == tmp))
	{
		printf("%d ",tmp->data);
		tmp = tmp->next;	
	}
	printf("%d ",tmp->data);
	printf("\n");
}


int main()
{
	int size;
	scanf("%d",&size);
	LIST list;
	list.size = 0;
	list.head = NULL;
	list.tail = NULL;
	
	create(&list,size);
	
	//List_Test(&list);
	
	int start,num;
	scanf("%d%d",&start,&num);
	if (start == 1) start = size;
	else start --;
	NODE* startNode = list.head;
	start --;
	while(start != 0)
	{
		startNode = startNode->next;
		start --;
	}
	
	while(!(list.size == 0))
	{
		if (list.size == 1)
		{
			printf("%d\n",startNode->data);
			free(startNode);
			return 0;
		}
		NODE* tmp = startNode->next;
		free(startNode->next);
		printf("%d ",startNode->next->data);
		startNode->next = tmp->next;
		for (int i=2;i<=num;i++)
		{
			startNode = startNode->next;
		}
		list.size --;
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值