1. 程式人生 > >演算法實現——約瑟夫問題

演算法實現——約瑟夫問題

約瑟夫環問題描述:

約瑟夫環問題起源於一個猶太故事。問題大意如下:
羅馬人攻佔了喬塔帕特,41個人藏在一個山洞中躲過了這場浩劫。其中包括了Josephus和他的一個朋友。剩餘39人不想屈服羅馬人,決定集體自殺。大家決定了一個自殺方案,由41個人組成一個圓圈,第一個人開始順時鐘報數,報數為三的人就馬上自殺,然後由下一個人重新開始報數,仍然報數為3就自殺。。。。。直到所有人都死亡
輸出他們的自殺順序

思路:迴圈連結串列初始化、刪除操作

本來以為是很簡單的一道題,結果自己寫的時候才知道,各種奇葩錯誤。傷不起啊,重現錯誤,以及修正過程,以此為鑑。

typedef struct node{
	int num;
	node* next;
} *pnode;
pnode initialize(int n){
	pnode head = new node;
	pnode pre=head;
	//head->next = 0;
	head->num = n;
	int i = 1;
	while (n){
		pnode p = new node;
		p->num = i;
		
		pre->next = p;
		pre = p;
		n--;
		i++;
	}
	pre->next = head->next;
	return head;
}
void yusefu(pnode head){
	int cnt = 1;
	int n = head->num;
	int *no = new int[head->num];
	pnode p = head->next;
	pnode pre=p;


	while (n){
		while (cnt!=3)
		{
		//	p = pre;
			pre = p;
			p = p->next;
			cnt++;
			cout << p->num <<"cnt"<<cnt<< endl;
		}
		cnt = 0;
		pre->next = p->next;
		no[head->num - n] = p->num;
		n--;
		delete p;
		p = pre;
	}
	
	for (int i = 0; i < head->num; i++){
		cout << no[i] << '\t';
		if (i == 10)cout << endl;
	}
	
	delete[]no;
}
int main(){
	// 約瑟夫環問題:
	cout << "約瑟夫環問題 input n" << endl;
	int n;
	cin >> n;
	pnode ph=initialize(n);
	yusefu(ph);
}

首先是初始化錯誤,第一次寫的時候沒注意,直接把各個node的num值設定成與n相等了,結果就是倒序的;後來除錯的時候 解決;

其次函式yuesefu()裡面,起初沒有第6行,pre=p的賦值,導致編譯器警告,後加上;再次執行,因為22行把p delete了,導致進入內層迴圈的時候,p指標內容無效,錯誤。自以為是地加上了第12行,以為這樣就可以了,沒有想到這才是噩夢的開始。

輸出的結果怎麼都是不對的,各種除錯,各種檢查,前前後後折騰了一個多小時,最後才恍然大悟,就因為加上了那一行,導致了本質上沒有刪除連結串列。最後終於找到原因了,但是不加又會報錯,怎麼辦?終於靈機一動才想起來在23行加上。。。

哎,發現自己還是弱爆了。。。。。