題目:
(2)一個旅行社要從n個旅客中選出一名旅客,爲他提供免費的環球旅行服務。旅行社安排這些旅客圍成一個圓圈,從帽子中取出一張紙條,用上面寫的正整數m(<n)作爲報數值。遊戲進行時,從第一個人開始按順時針方向自1開始順序報數,報到m時停止報數,報m的人被淘汰出列,然後從他順時針方向上的下一個人開始重新報數,如此下去,直到圓圈中只剩下一個人,這個最後的倖存者就是遊戲的勝利者,將得到免費旅行的獎勵。
編程對某個給定的n = 8與m = 3,給出被淘汰出列的旅客編號,以及最終的倖存者。
代碼我是這麼寫的:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int number;
struct node * nextPtr;
}Node;
Node * init(int n);
void delete(Node *sPtr, int n);
int main()
{
int m, n, i;
Node * head = NULL;
Node * temp = NULL;
scanf("%d%d", &m, &n);
head = init(n);
temp = head;
while (temp->nextPtr != temp)
{
int deleteNumber;
for (i=1; i<m; i++)
{
temp = temp->nextPtr;
}
deleteNumber = temp->number;
temp = temp->nextPtr;
delete(head, deleteNumber);
}
printf("Survivors is %d\n", temp->number);
free(temp);
return 0;
}
Node * init(int n)
{
int i;
Node * curNode = NULL;
Node * head = NULL;
curNode = (Node *)malloc(sizeof(Node *));
curNode->number = 1;
curNode->nextPtr = NULL;
head = curNode;
for (i=1; i<n; i++)
{
Node * newNode;
newNode = malloc(sizeof(Node *));
newNode->number = i + 1;
newNode->nextPtr = NULL;
curNode->nextPtr = newNode;
curNode = newNode;
}
curNode->nextPtr = head;
return head;
}
void delete(Node *sPtr, int n)
{
Node * prePtr=NULL;
Node * curPtr=NULL;
curPtr = sPtr;
while (curPtr->number != n) {
prePtr = curPtr;
curPtr = curPtr->nextPtr;
printf("%d-->", prePtr->number);
}
prePtr->nextPtr = curPtr->nextPtr;
printf("delete %d\n", curPtr->number);
free(curPtr);
}
輸入m=3,n=8運行結果是:
##############################
./a.out 3 81-->2-->delete 31-->2-->4-->5-->delete 6段錯誤
##############################
最後面發現錯在head這個Node指針變量,本意是想用來保存單向循環鏈表的頭節點信息,然後通過每次從head開始遍歷鏈表來刪除節點,而
delete(head,deleteNumber);
這一句依賴head,在第三次循環刪除節點1之後,head就相當於指向一個被收回的地址,就產生段溢出錯誤了。
最後修改程序邏輯,使用temp來傳參給delete函數來開始遍歷鏈表就OK了,如下改動:
// Node * head = NULL;
// head = init(n);
// temp = head;
上面三行替換成temp = init(n);
//delete(head, deleteNumber);
上面這行替換成delete(temp, deleteNumber);
運行結果:
./a.out
3 8
4-->5-->6-->7-->8-->1-->2-->delete 3
7-->8-->1-->2-->4-->5-->delete 6
2-->4-->5-->7-->8-->delete 1
7-->8-->2-->4-->delete 5
4-->7-->8-->delete 2
4-->7-->delete 8
7-->delete 4
Survivors is 7