• 约瑟夫环


       要求:约瑟夫环的一种描述为:序号为1,2,...,n的n个人按顺时针方向围坐一圈,每个人持有一个密码(正整数),开始时任选一个数作为报数上限m,从第一个人开始顺时针自1开始顺序报数,报到m时停止报数,报的m的人出列,将他的密码作为新的m值,从他开始在顺时针方向的下一个人开始重新从1报数,如此下去,直至所有人全部出列,请设计一个程序,求出出列顺序。

    如:当m的初始值为20,n=7,7个人的密码依次为:3,1,7,2,4,8,4,出列的顺序为6,1,4,7,2,3,5.

    思路:因为n个人围坐一圈,所以可以很自然的想到用单向循环链表作为存储结构来模拟此过程,然后按一定的条件删除某个结点,将该结点打印出来。

    基于此思路代码如下:
    # include<stdio.h>
    # include<stdlib.h>
    # include<windows.h>
    typedef struct people
    {
    	int order; 
    	int password; 
    	int nextorder;
    	struct people * pnext;
    }p,*linklist;
    void main()
    {
    	int n,m;
    	printf("请输入人的个数n
    ");
    	scanf("%d",&n);
    	int count =0;
    	int i=1;
    	linklist phead=(linklist)malloc(sizeof(p));
    	linklist ptail=phead;
    	while(count!=n)//构建约瑟夫环
    	{
    	
    		linklist pnew=(linklist)malloc(sizeof(p));
    		pnew->order=i;
    		pnew->nextorder=i;
    		printf("请输入该人的密码
    ");
    		scanf("%d",&pnew->password);
    		ptail->pnext=pnew;
    		pnew->pnext=NULL;
    		ptail=pnew;
    		i++;
    		count++;
    	}
    	ptail->pnext=phead;
    	printf("请输入报数上限值m
    ");
    	scanf("%d",&m);
    	linklist ptemp=phead;
    	linklist pre; 
    //	linklist ptemp=phead->pnext;
    	int k=0;
    	while(ptemp->pnext!=ptemp)//模拟出列过程
    	{
    		pre=ptemp;
    		ptemp=ptemp->pnext;
    		if(ptemp==phead) 
    		{
    			pre=ptemp;
    			ptemp=ptemp->pnext;
    		}
    		k++;
    		if(k==m)
    		{
    			printf("%d ",ptemp->order);
    			m=ptemp->password; 
    			pre->pnext=ptemp->pnext;
    			//linklist p=ptemp;
    			free(ptemp);
    			//ptemp=pre->pnext;不能这样写,因为头结点phead中无数据,如果是最后一个元素删除了则加1后ptemp到了phead,
    			//k=1;			   而phead中无数据所以多算了一步
    			ptemp=pre;
    			k=0;
    		}
    
    	}
    }
    程序运行结果如下:


  • 相关阅读:
    python-列表基本方法
    成员/身份运算
    python-字符串常用方法
    python基础知识1
    jmeter_性能测试及报告分析
    Day3_linux_工作目录切换命令
    Day2_linux_查看系统状态
    Day1_liunx_常用系统工作命令
    互联网是有记忆的
    第3章 Python基础
  • 原文地址:https://www.cnblogs.com/hainange/p/6334079.html
Copyright © 2020-2023  润新知