試題四(共15分)
閱讀以下說明和c函數(shù),填補c函數(shù)中的空缺(1)—(5),將解答寫在答題紙的對應(yīng)欄內(nèi)。
【說明】
約瑟夫問題如下所述:有n個人(編號為1~n)圍成一圈,從第一個人開始,按照順時針方向從1開始計數(shù)到m(即數(shù)到第m個人),讓其出圈,然后再從其順時針方向的下一個人開始,依次計數(shù)到m并讓其出圈,重復(fù)這個過程,直到所有人都出圈,試給出出圈者的順序。
以n=5,m=3為例,其中圈順序為3,1,5,2,4,過程如下圖所示。
下面的函數(shù)Joseph()在單向循環(huán)鏈表表示的基礎(chǔ)上訴出圈的過程。
n為5時的單向循環(huán)鏈表結(jié)構(gòu)如下圖所示。
鏈表的結(jié)合類型定義如下:
typedef struct Node {
int no;
struct Node*next;
}Node,*LinkList;
函數(shù)Joseph(LinkList tail,int n,int m)的處理思路如下:
(1)用k計數(shù),每次都從0開始,當計數(shù)到m-1時結(jié)束本次計數(shù);
(2)通過指針p查找出圈者所對應(yīng)的結(jié)點,當K的值等于是m-1時,P應(yīng)指向出圈者對應(yīng)結(jié)點的前驅(qū)結(jié)點;
(3)通過刪除結(jié)點表示出圈處理;
(4)當m大于圈中剩余人數(shù)時,為了避免重復(fù)計數(shù),用模運算修改m的值;
(5)計數(shù)和刪除操作完成后再恢復(fù)m的原值;
【C函數(shù)】
void Joseph(LinkList tail,int n,int m)
{ /*單循環(huán)鏈表包含n個結(jié)點,tail為鏈表的尾指針,m為計數(shù)值*/
LinkList p,q;
int k,i,old_m=m;
p=tail;
for(i=n;i>1;--i) { /*i 表示圈中剩余人數(shù)*/
m=m%i; /*避免重復(fù)計數(shù)*/
if(0==m) m=(1);
k=0;
while(k<(2)) {
(3);
k++;
}
printf("%d\n",(4)); /*輸出出圈者的編號*/
q=p->next;
(5)=q->next; /*刪除出圈者對應(yīng)的結(jié)點*/
free(q);
m=old_m;
}
printf(“%d\n”,p->No);
}