约瑟夫环问题

约瑟夫环问题

[问题描述]
设有n个人围坐一圈,现从某个人开始报数,数到m的人出列,接着从出列的下一个人开始重新报数,数到M的人又出列,如此下去,直到所有人都出列为止。试设计确定它们的出列次序序列的程序。

[基本要求]
选择单向循环链表作为存储结构模拟整个过程,并依次输出出列的各人的编号。


解决:

/*头文件 Joseph.h*/
#ifndef _JOSEPH_H__
#define _JOSEPH_H__
 
#include
#include
#include
 
typedef struct Joseph{
	int num;
	struct Joseph* next;
}Joseph,*pJoseph;
 
pJoseph CreateJoseph(int n);
void joseph_r(pJoseph head, int k, int m);
 
#endif
/*主函数实现
#include"Joseph.h"
 
pJoseph CreateJoseph(int n)
{
	int i = 0;
	pJoseph head = NULL;
	pJoseph tail = NULL;
	head = (pJoseph)malloc(sizeof(Joseph));
	head->next = head;   
	head->num = 1;
	tail = head;
	for (i = 2; i <= n; i++) 
	{
		pJoseph New = (pJoseph)malloc(sizeof(Joseph));
		New->num = i;
		New->next = tail->next;
		tail->next = New;
		tail = New;
	}
	return head;
}
 
void joseph_r(pJoseph head, int k, int m)
{
	assert(head);
	pJoseph cur = NULL;
	pJoseph prev = NULL;
	pJoseph del = NULL;
	cur = head;
	if (k == 1 && m == 1)  
	{
		while (cur->next != head)
		{
			printf("%d ", cur->num);
			del = cur;
			cur = cur->next;
			free(del);
		}
		printf("%d\n", cur->num);
	}
 
	else if (k != 1 && m == 1)    
	{
		while (cur->num != k)
		{
			prev = cur;
			cur = cur->next;
		}
		while (head->next != head)
		{
			del = cur;
			prev->next = cur->next;
			cur = cur->next;
			printf("%d ", del->num);
			if (cur == head)
			{
				head = cur->next;
			}
			free(del);
		}
		printf("%d\n", head->num);
	}
	else
	{
		int i = 0;
		while (cur->num != k)
		{
			cur = cur->next;
		}
		while (head->next != head)
		{
			for (i = 1; i < m - 1; i++)  
			{
				cur = cur->next;        
			}                          
			del = cur->next;
			cur->next = del->next;
			printf("%d ", del->num);
			if (del == head)
			{
				head = del->next;
			}
			free(del);
			cur = cur->next;
		}
		printf("%d\n", head->num);
	}
}
/*测试*/
void test()
{
	pJoseph head;
	head = CreateJoseph(10);
	joseph_r(head, 1, 1);
}
int main()
{
	pJoseph head;
	test();
	head=CreateJoseph(10);
	joseph_r(head, 2, 2);
	getchar();
	return 0;
}

你可能感兴趣的:(数据结构笔记)