链表实现约瑟夫环

前几天考网管的时候用到了数据结构课本,想当年那么头疼的一本书,现在突然觉得挺有意思的,就想回过头来看看。今天周六,上午无聊的在实验室待着,下午来的时候拿起了数据结构的课本。第一章链表中有一个很著名的约瑟夫环的问题,想当年也是老师留的题目之一,当时这一块有好多问题,包括结构体的定义,包括malloc函数的使用,包括链表的构造和实现。下午就重新对这一块进行了学习。

约瑟夫问题的一种描述是:编号为12nn个人按顺时针方向围坐一圈,每人持一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。 基本要求 利用单向循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。 测试数据 M的初值为20n=77各人的密码依次为3172484。

主要用到的知识:线性表的链式表示,单向循环表。

下面是我的代码:

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

typedef struct Lnode{
	int code;
	struct Lnode *next;
	int number;
}Lnode,*LinkList;//先定义结构体链表,每个结构体存储密码和下一个人的指针,定义一个结构体变量和指针变量


//创建7个人的链表


LinkList InitLinkList(int number)
{
	int n;

    LinkList L,p,header;

	 	header=(LinkList)malloc(sizeof(Lnode));//用来保存第一个人的指针
     
  


  	L=(LinkList)malloc(sizeof(Lnode));//保存头结点
	

   
  
  for(int i=0;i<number;i++)
  {
     p=(LinkList)malloc(sizeof(Lnode));
	 printf("请输入密码");
	 scanf("%d",&n);
	 p->code=n;
     p->number=i+1;
	 L->next=p;
	 L=p;
     if(i==0)
       header=L;//此时header指向第一个人
  
  }
//结束之后将最后一个指针指向第一个人
   L->next=header;

  return header;

}
 


int main()
{
	int number,m,a;
	LinkList header;

   printf("请输入人数");
  
  scanf("%d",&number);
  printf("请输入初始密码");
  scanf("%d",&m);
  header=InitLinkList(number);
  
  
  
  while(number>0)
  {
    a=m%number;
    if(a<2)
		a=a+number;
	  
    for(int i=0;i<a-2;i++)
	{
	
	   header=header->next;


	}
  
  printf("%d",header->next->number);//header对应的下一个节点就是要删除的节点

  m=header->next->code;//将这个节点对应的密码置为m
  
 
  header->next=header->next->next;//
  
  header=header->next;

 
  number--;

  
  }
  
return 0;

}
现在写这个程序基本没什么难度了,当初也是费了很大功夫也没搞定。想想有些曾经以为很难的事情,再回过头去做好像也不是很难了。今天非常巧合的遇到了本科舍友大黄同学,听他说本科学了四年的游泳也没学好,反倒是最近重新去学,感觉也不是那么难了。不仅学习,生活也是这样,所以遇到事情,不要急,说不定在将来的某一天,你就找到了解决的办法了。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值