近期重溫資料結構,發現有不少書籍沒有将成品可運作的資料結構代碼放出,是以在這挖個坑,後期會将常見資料結構以C語言形式實作,并且盡可能讓隻看了書但是代碼能力較弱的讀者也能看懂實作。本人能力有限,不足之處還請大家多多指出。

下面放出循環連結清單實作的約瑟夫環,運作環境為vs2019,無報錯
#include<stdio.h>
#include<stdlib.h>
#pragma warning(disable:4996);
//約瑟夫環問題實作
typedef struct Node {//建立結點
int data;
struct Node* next;
}Node, * Point;
void tailcreate(Point* head, int n) {//建立結點個數為n的連結清單,思想為先來後到,不斷把新結點放在連結清單尾(尾插)
Point p, s;
p = *head;//循環指針p從頭結點開始
for (int i = 2; i <= n; i++) {
s = (Point)malloc(sizeof(Node));
s->data = i;
p->next = s;//把新結點連在頭節點的後面
p = s;//此時新結點s變成了最後的結點,讓下一個結點在s的後面插入,循環往複
}
p->next = *head;
}
void find(Point* head, int lotcation, int num) {//location為從第幾個開始,num為數到幾
Point p = *head;
Point s;
for (int i = 0; i < lotcation - 1; i++) {//此時p移動到了第location位置的結點
p = p->next;
}
printf("第%d個結點的資料是%d\n", lotcation, p->data);
while (1) {//每次循環删除一個結點,直到隻剩一個結點
if (p == p->next) {
printf("最後勝利者是%d", p->data);
break;
}
else {
for (int j = 0; j < num - 2; j++) {//開始計數,p移動到被删除的結點的前一個結點
p = p->next;
}
printf("出列資料是%d\n", p->next->data);
s = p->next;
p->next = p->next->next;//将被删除結點的後一個結點與被删除結點的前一個結點連結起來
free(s);//釋放被删除結點的空間
p = p->next;//此時讓p移動到被删除結點的下一個結點
}
}
}
int main() {
Point head;
int num, k, m;
head = (Point)malloc(sizeof(Node));/*申請一塊Node類型大小的記憶體,
并強制轉化為結點指針類型,建立頭結點head*/
head->data = 1;
head->next = NULL;
printf("參與人數:\n");
scanf("%d", &num);
printf("從編号幾開始:\n");
scanf("%d", &k);
printf("數到幾的出列:\n");
scanf("%d", &m);
tailcreate(&head, num);
find(&head, k, m);
return 0;
}