數據結構(一)線性表循環鏈表之約瑟夫環
阿新 • • 發佈:2018-08-05
cli amp tlist isp alloc 個人 pla 初始 ont
(一)前提
41個人報數,1-3,當誰報數為3,誰就去嗝屁。現在獲取他們嗝屁的順序
(二)實現結構
順序:3->1->5->2->4
(三)代碼實現
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <time.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 typedef int ElemType; typedef int Status; typedef老方法聲明函數,結構體等struct Node { ElemType data; struct Node* next; }Node; typedef struct Node* CLinkList; //四個基本操作,初始,清空,判斷是否為空,獲取長度 Status InitList(CLinkList* L, int n); //指定開始位置來打印數據 void PrintListByIndex(CLinkList rear, int index); //用來打印鏈表 void PrintList(CLinkList rear);
int main() { CLinkList L= NULL; CLinkList p; ElemType e; int n = 41; int m = 3; int i; InitList(&L,n); //現在L指向第一個結點 PrintList(L); while (L!=L->next) //判斷頭尾指針是否指向相同,相同則元素都不存在 { for (i = 1; i < m-1; i++) L = L->next; //找到要刪除的那個結點的前一個 printf("%d->", L->next->data); //獲取被殺死的人的數據 p = L->next; //獲取被殺死的人 L->next = p->next; free(p); L = L->next;//指向新的下一個元素 } printf("%d", L->data); //輸出最後一個 free(L); system("pause"); return 0; } //四個基本操作,初始,清空,判斷是否為空,獲取長度 //初始化帶有頭結點的鏈表 Status InitList(CLinkList* L,int n) { CLinkList rear, q; //rear是尾結點 ElemType item; rear = q = NULL; srand(time(0)); for (int i = 0; i < n;i++) { item = rand() % 100; if (*L==NULL) { *L = (CLinkList)malloc(sizeof(Node)); if (!(*L)) return ERROR; (*L)->data = item; (*L)->next = *L; //自己指向自己 rear = *L; //設置尾指針位置 } else { //生成新的節點,根據尾指針添加節點,並實時更新尾指針。註意這裏數據插入是尾插法 q = (CLinkList)malloc(sizeof(Node)); q->data = item; q->next = rear->next; rear->next = q; rear = q; } } return OK; }
//用來打印鏈表 void PrintList(CLinkList L) { CLinkList q = L; //獲取頭指針 while (q->next != L) { printf("%d ", q->data); q = q->next; } printf("%d\n", q->data); }老方法打印鏈表PrintList
(四)擴展提升
1-N個人,按順時針一圈,每個人手中有一個密碼(一個正整數),
我們(裁判)定義第一個開始值為M,從第一個人開始自1開始報數,直到報數為M,那麽這個人就退出,將他手中的密碼值作為新的開始值,
一直循環直到所有的人都退出
情景演示
修改代碼
int main() { CLinkList L = NULL; CLinkList p; ElemType e; int n = 19; int m; int i; InitList(&L, n); //現在L指向第一個結點 PrintList(L); scanf("%d", &m); //初始密碼值我們輸入 m--; //下面while循環都是由前一結點開始計算距離的,而我們這裏是從第一個結點直接開始的,需要找到他的前一個節點,或者將走的步數減一即可 while (L != L->next) //判斷頭尾指針是否指向相同,相同則元素都不存在 { for (i = 1; i <= m - 1; i++) L = L->next; //找到要退出的那個人的前一個人 printf("%d->", L->next->data); //獲取將要退出的人的密碼 p = L->next; //獲取即將退出的人 L->next = p->next; m = p->data; //更新密碼值 free(p); //每次返回的都是退出結點的前一個節點,方便計算當密碼為1的情況(重點)
} printf("%d\n", L->data); //輸出最後一個人 free(L); system("pause"); return 0; }
數據結構(一)線性表循環鏈表之約瑟夫環