約瑟夫環的兩種實現

記得大一學數據結構的時候用節點構成了一個循環鏈做過這個題,前幾天偶然想到,爲什麼不用數組來做呢?


用循環鏈做的

/*
 **********************************************************
 * 解法
 *
 * 使用一個循環鏈,其中包含兩個元素,一個爲指向下一個人的
 * 節點,一個爲是否出列的標記
 *
 **********************************************************
 */
#include <stdio.h>
#define M 30	//假設有30個人圍成一個圈
#define N 13	//出列13個
#define L 9		//第9個人出列

struct node
	{
		int nextp;	//指向下一個節點
		int in_out;		//是否出列的標誌
	} link[M+1];	//M個人的數組,下標0未曾使用

main (void)
{
	int i, j, k;	//作爲計數器

	printf ("The circle is: + mean in; - mean out \n");

	for (i = 1; i < M+1; i++)
	{
		link[i].nextp = i + 1;	//指向下一個節點
		link[i].in_out = 1;		//標誌爲1,表示都尚未出列
	}

	link[30].nextp = 1;		//最後一個指向第一個節點,形成一個循環鏈

	j = 30;		//從指向第一個節點的位置開始計數

	for (i = 0; i < N; i++)		//i:出列人數的計數器
	{
		for (k = 0; ;)	//k:出列人的計數器
		{
			if (k < L)		
			{
				j = link[j].nextp;		//修改指針,繼續計數
				k += link[j].in_out;	//遍歷查找出列的人。因爲已出列的標記爲零,所以可循環查找
			}
			else
				break;
		}

		link[j].in_out = 0;		//將出列的人標記爲0
	}

	printf ("The result is:");
	for (i = 0; i < M; i++)	//輸出結果
	{
		printf (" %c ", link[i+1].in_out ? '+': '-');
	}	
	printf ("\n");

	return 0;
}


運行之後


wKioL1VAic-TqOf5AAEDBpZ0Osg233.jpg


用數組做的感覺就清晰了很多

#include<stdio.h>

#define M 30	//假設有30個人圍成一個圈
#define N 13	//出列13個
#define L 9		//第9個人出列

int main (void)
{
	int i, j, k,num,t;	//作爲計數器
	int circus[30];

	printf ("The circle is: + mean in; - mean out \n");

	for (i = 0; i < M; i++)
		circus[i]=1;

	k=-1;
	for (i = 0; i < N; i++)		//i:出列人數的計數器
	{
		num=0;
		while(num<L)
		{
			k++;
			num+=circus[k%M];		
		}
		circus[k%M]=0;
	}

	printf ("The result is:");
	for (i = 0; i < M; i++)	//輸出結果
	{
		printf (" %c ", circus[i] ? '+': '-');
	}	
	printf ("\n");

	return 0;
}


運行之後

wKiom1VAiMij11JhAAEDBpZ0Osg078.jpg

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章