简单的循环链表

什么是循环链表?

链表头尾相连,将链表的最后一个节点的指针域指向他的头节点,形成一个环状,这就叫循环链表。

什么是瑟夫环问题?

约瑟夫环问题,是一个经典的循环链表问题,题意是:已知 n 个人(以编号1,2,3,…,n分别表示)围坐在一张圆桌周围,从编号为 k 的人开始顺时针报数,数到 m 的那个人出列;他的下一个人又从 1 还是顺时针开始报数,数到 m 的那个人又出列;依次重复下去,要求找到最后出列的那个人。

循环链表实现很简单,接下来我们来实际应用到瑟夫环问题中,链表第一步,首先创建一个结构体
#include <stdio.h>
#include <stdlib.h>
//这里不过多解释了
typedef struct node 
{
	int data;
	struct node *next;
	
}link;

复制代码
初始化链表

link *initCyclic(int n)
{
    int i; 
    link * head=(link*)malloc(sizeof(link));//申请空间 定义头部节点数据
    head->data=1;
    head->next=NULL;
    link * cyclic=head;//创建一个指针 不至于丢失头地址
    for (i=2; i<=n; i++) {
        link * body=(link*)malloc(sizeof(link));
        body->data=i;
        body->next=NULL; 
        cyclic->next=body;
        cyclic=cyclic->next;
    }
    cyclic->next=head;//这里首尾相连,这样就形成一个环。
    return head;
}

复制代码
实际应用到瑟夫环问题上
void circulation(link *head,int k,int m)
{
	link *tail;
	link *p = head;
	int i = 1;
	while (p->data != k) {//k是开始报数的人,这里找到k的指针地址
		tail = p;
		p = p->next;
	}

	while (p->next != p) {//从k开始发言
		for (i=1;i<m;i++) {//判断数到m的人出列
			tail = p;//出列者的上一个节点
			p = p->next;//出列者的指针
		}
		
		tail->next = p->next;//将上一个节点的指针域改成下个节点的指针域
		printf("出列人的编号为:%d\n", p->data);
		free(p);//释放内存
		p = tail->next;
	}
	printf("出列人的编号为:%d\n",p->data);
	free(p);
}

复制代码
开始运行
int main() {
    printf("输入圆桌上的人数n:");
    int n;
    scanf("%d",&n);
    link * head=initCyclic(n);
    printf("从第k人开始报数:");
    int k;
    scanf("%d",&k);
    printf("数到m的人出列:");
    int m;
    scanf("%d",&m);
    circulation(head, k, m);
    return 0;
}
复制代码
运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值