实战数据结构(4)_循环单链表解决约瑟夫问题

/************************************************************************/
/* author:  lynnbest	2013.8.24
约瑟夫问题:
	有n个人,编号为1,2,3...n围成一个圆圈,按照顺时针方向从编号为k的人
开始报数,报数为m的人出列,她的下一个人重新开始从1报数,数到m的人出列
如此重复下去,知道所有人都出列,编写一个算法,要求输入n,k,m按照出列的
顺序输出编号
exp:
1,2,3,4,5,6,7一圈	n=8,k=2,m=3
则按照输出的编号为:4 7 2 6 3 1 5 8
                                                                     */
/************************************************************************/
/************************************************************************/
/* 思路:
1.先创建一个循环链表
2.查找到k元素位置
3.查找到m元素位置
		查找到后,先记录下一个节点位置copynode=startnode->next
		然后删除节点
跳转到2
4.打印最后一个节点 free()
                                                                     */
/************************************************************************/
#include 
#include 

typedef struct node 
{
	int data;
	struct node *next;
}listnode;

void josephus(listnode *h,int n,int k,int m);
void printflist(listnode *h);
listnode *CreateCircleList(int n);
void main()
{	
	printf("    约瑟夫问题	\n");
	printf("----by lynnbest ----\n\n");
	int n,k,m;
	printf("输入n,k,m\n");
	scanf("%d,%d,%d",&n,&k,&m);
	listnode *h=CreateCircleList(n);//创建一个循环列表
	printflist(h);
	printf("依次退出的编号为:\n");
	josephus(h,n,k,m);

}

void josephus(listnode *h,int n,int k,int m)
{
	listnode *startnode,*copynode,*pre;
	startnode=h;
	int i;
	//查找到k位置
	while(k-1)
	{
		startnode=startnode->next;
		k--;
	}
	
	//查找m位置
	while(startnode->next!=startnode)//当该节点不是最后一个节点
	{	
		
		for(i=1;inext; //startnode为要删除的节点 pre为其前驱节点
		}
		copynode=startnode->next;	//备份当前要删除位置节点的下一个节点
		printf("%3d",startnode->data);
		pre->next=startnode->next;//删除节点
		free(startnode);
		startnode=copynode;
	}	
	printf("%4d\n",startnode->data);
	free(startnode);
}

void printflist(listnode *h)
{	
	printf("当前链表元素为:\n");
	listnode *p=h;
	while(p->next!=h)
	{
		printf("%4d",p->data);
		p=p->next;	//漏了
	}
	printf("%4d\n",p->data);
}

listnode *CreateCircleList(int n)
{	
	listnode *head=NULL,*newnode,*pre;
	for(int i=1;i<=n;i++)
	{
		if(NULL==(newnode=(listnode *)malloc(sizeof(listnode))))
		{
			printf("malloc新节点失败\n");
			exit(-1);
		}
		newnode->data=i;
		if(NULL==head)	//不带头节点的怎么创建 技巧
			head=newnode;
		else
			pre->next=newnode;
		pre=newnode;
	}
	newnode->next=head;//构成循环链表
	return head;
}
实战数据结构(4)_循环单链表解决约瑟夫问题_第1张图片

你可能感兴趣的:(数据结构与算法,实结构战数据)