數據結構與算法實驗報告
約瑟夫生死游戲
姓名:孫瑞霜
一、實驗目的
1、熟練掌握學習的每種結構及其相應算法;
2、理論聯系實際,會對現實問題建模並設計相應算法。
3、優化算法,使得算法效率適當提高
二、實驗要求:
1. 認真閱讀和掌握教材上和本實驗相關的內容和算法;
2. 上機將各種相關算法實現;
3. 實現上面實驗目的要求的功能,並能進行簡單的驗證。
三、實驗內容
認真學習 學習通->數據結構->資料->數據結構實驗指導書--陳越版,從第二章進階實驗1~10中任選一個來實現,編寫程序,輸入給定的數據,能得到給定的輸出。總結算法思想、畫出流程圖,並思考程序有無改進空間,如何改進。
三、算法描述
選擇實驗2“約瑟夫生死游戲”。
該實驗采用循環鏈表將30個數據串聯起來,首先創建循環鏈表,其次進入刪除函數,刪除函數中采用雙重循環,外循環負責控制刪除數據的個數,內循環負責找出每次要刪除人的位置的前一個位置,然后定義一個指針指向刪除位置,將刪除位置的前一個位置和后一個位置連接,輸出刪除位置的數據和余下的數據,釋放刪除的節點。
函數還可以改進,比如從根節點開始,直接找到刪除的位置。
四、詳細設計
五、程序代碼
#include<stdio.h>
#include<stdlib.h>
/* 定義鏈表節點類型 */
typedef struct node{
int data;
struct node * next;
}linklist;
linklist * Init(int n,linklist * Ptrl){
linklist *p,*q;
int i;
Ptrl=(linklist *)malloc(sizeof(linklist));
q=Ptrl;
for(i=1;i<n;i++)
{
p=(linklist *)malloc(sizeof(linklist));
q->data=i;
q->next=p;
q=p;
}
q->data=n;
p->next=Ptrl;
Ptrl=q;
return Ptrl; //此時Ptrl指向鏈表的最后一個位置
}
void OutList(int n,int i,linklist *Ptrl){ //將幸存的人的編號輸出
linklist *s;
s=Ptrl->next;
for(int t=1;t<=n-i;t++,s=s->next)
printf("%d ",s->data);
}
linklist * Delete(int n,int k,linklist *Ptrl)
{
int i,j;
linklist *p,*q;
p=Ptrl;
for(i=1;i<=n/2;i++) //剔除一半的人
{
for(j=1;j<=k-1;j++) //循環找到要刪除的前一個位置 用指針p表示
p=p->next;
q=p->next; //q此時指向要刪除的位置
p->next=q->next; //將要刪除的位置的前一個位置與要刪除的位置的后一個位置連接
printf("\n\n第%d次被拋下海的序號為:",i);
printf("%d\n",q->data);
printf("船上還剩下幸存者的序號:\n");
if(q->data==Ptrl->data) //如果剛好刪除最后一個位置
Ptrl=p;
OutList(n,i,Ptrl); //將幸存的人的編號輸出
free(q);
}
return Ptrl;
}
int main(){
linklist * Ptrl;
int n,k;
printf("船上的總人數(n)是:");
scanf("%d",&n);
printf("從第k個人開始拋下海:");
scanf("%d",&k);
Ptrl=Init(n,Ptrl);
Ptrl=Delete(n,k,Ptrl);
}
六、測試和結果
七、用戶手冊
打開Dev c++,將五部分代碼拷貝進去,點擊運行,按照提示輸入數據,最后得出結果,關閉程序。