• 约瑟夫解决问题的循环链表


     1、约瑟夫问题的

            编号为1,2。....,N的N个人按顺时针方向围坐一圈,每人持有一个password(正整数)。一開始任选一个正整数作为报数上限值M。从指定的人K開始按顺时针方向自1開始顺序报数,报到M时停止报数。报M的人出列,将他的password作为新的M值。从他在顺时针方向上的下一个人開始又一次从1报数,如此下去,直至所有人所有出列为止。

    试设计一个程序求出出列顺序。

            解决思路还是非常easy的,主要是要会熟练运用单循环链表的数据结构,通过单循环链表模拟围坐的一圈人。然后依据对应的password进行报数。然后删除对应的链表节点。

    2、程序(经过測试)

    /*宏定义和单链表类型定义*/

    #define ListSize 100
    typedef int DataType;
    
    typedef struct Node
    {
    	DataType data;
    	struct Node *next;
    }ListNode,*LinkList;

    /*函数声明*/

    LinkList CreateCycList(int n);                  /*创建一个长度为n的循环单链表的函数*/
    void Josephus(LinkList head,int n,int m,int k); /*在长度为n的循环单链表中。报数为编号为m的出列*/
    void DisplayCycList(LinkList head);             /*输出循环单链表*/
    void test_Josephus();                           /* 測试函数 */
    void Josephus(LinkList head,int n,int m,int k)
    {  /*在长度为n的循环单链表中。从第k个人開始报数。数到m的人出列*/
    	ListNode *p,*q;
    	int i;
    	p=head;
    	for(i=1;i<k;i++)     /*从第k个人開始报数*/
    	{
    		q=p;
    		p=p->next;
    	}
    	while(p->next!=p)
    	{
    		for(i=1;i<m;i++) /*数到m的人出列*/
    		{
    			q=p;
    			p=p->next;
    		}
    		q->next=p->next;  /*将p指向的结点删除,即报数为m的人出列*/
    		printf("%4d",p->data);
    		free(p);
    		p=q->next;           /*p指向下一个结点,又一次開始报数*/
    	}
    	printf("%4d
    ",p->data);
    }
    LinkList *CreateCycList(int n)   
    {  
    	LinkList *head=NULL;
    	ListNode *s,*r;
    	int i;
    	for(i=1;i<=n;i++)
    	{
    		s=(ListNode*)malloc(sizeof(ListNode));     //申请节点内存
    		s->data=i;
    		s->next=NULL;
    		if(head==NULL)
    			head=s;
    		else
    			r->next=s;
    		r=s;
    	}
    	r->next=head;            //将尾节点指向头节点,构成循环链表
    	return head;
    }
    void DisplayCycList(LinkList *head)
    {  /*输出循环链表的每个元素*/
    	ListNode *p;
    	p=head;
    	if(p==NULL)
    	{
    		printf("该链表是空表");
    		return;
    	}
    	while(p->next!=head)/*假设不是最后一个结点,输出该结点*/
    	{
    		printf("%4d",p->data);
    		p=p->next;
    	}
    	printf("%4d
    ",p->data);/*输出最后一个结点*/
    }
    
    void test_Josephus()
    {
    	LinkList *h;
    	int n,k,m;
    	printf("输入环中人的个数n=");
    	scanf("%d",&n);
    	printf("输入開始报数的序号k=");
    	scanf("%d",&k);
    	printf("报数为m的人出列m=");
    	scanf("%d",&m);
    	h=CreateCycList(n);
    	printf("原始数据为:
    ");
    	DisplayCycList(h);
    	printf("选出的元素依次为:
    ");
    	Josephus(h,n,m,k);         
    
    }
    将 test_Josephus()函数放在main()函数中执行。结果例如以下:







    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    马云教会我一件事:拉出来的还可以再坐回去
    使用google MAP座標搜尋改善用戶體驗
    PHP树不需要递归
    PHP操作MongoDB技術總結
    10个你可能从未用过的PHP函数
    台企招聘一名PHP程序員
    002HC32F460(华大)+Air724UG(4G GPRS)基本控制篇(阿里云物联网平台)在阿里云物联网平台上一型一密动态注册设备(HC32F460+Air724UG)
    173华大单片机HC32F460系列flash存储方案
    001HC32F460(华大)+Air724UG(4G GPRS)基本控制篇(阿里云物联网平台)C#,网页,android,微信小程序,单片机等使用MQTT接入阿里云物联网平台
    003HC32F460(华大)+Air724UG(4G GPRS)基本控制篇(阿里云物联网平台)在阿里云物联网平台上一型一密动态注册设备(Android)
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4838741.html
Copyright © 2020-2023  润新知