鏈表的精髓

代碼
#include<bits/stdc++.h>//c++萬能頭文件,寫了這個其他頭文件不用寫
using namespace std;//使用名字空間,你不用管
typedef struct node//節點存放一個數據和指向下一個節點的指針
{
int data;//數據域
struct node *pnext;//指針域,而且必須指向下一個同類型的節點的指針變量 struct node這個類型
} Node;
Node *create(int n)//創建n個節點的循環鏈表,函數名前加*表示返回Node類型的指針
{
//先創建第1個節點
Node *p,*q,*head;//p,q,head為指向struct node類型的指針變量,可以為其賦值
int i;
p = (Node *)malloc(sizeof(Node));//malloc函數為p動態分配內存空間
head = p;//頭部也就是第一個節點
p->data = 1;
for(i = 2;i<=n;i++)//再創建剩余節點
{
q = (Node *)malloc(sizeof(Node));//添加新節點所以重新分配內存空間,動態分配
q->data = i;
p->pnext = q;//p在q前面所以p指向q
p = q;//這個時候p就得是q了,因為要往后創建 ,也就是說q就變成下一個節點的前驅
}
p->pnext = head;//最后一個節點指向頭部,形成循環鏈表
return head;
}
void Josephus(Node *head,int k,int m)//從編號為k(1<=k<=n)的人開始報數,數到m的那個人出列;
{
int i;
Node *p = head,*tmp1;
while(p->data != k)//p指向的節點data為k,先找到開始的數的那個位置
p = p->pnext;
while(p->pnext != p)//模擬報數的過過程直到剩下自己一個人的時候,這時只有一個他指向自己
{
for(i=1;i<m;i++)//數到第m個
{
tmp1 = p;//tmp1在這里用於記錄出局人的前一個人
p = p->pnext;
}
printf("%d ",p->data);//輸出出局的人的編號
//鏈表的精髓在下面這個部分,看我發的圖片,比數組好多了
tmp1->pnext= p->pnext;//只需改變指針指向的數據元素,就可以去掉出局的那個人,從他下一個位置的人開始數
free(p);//釋放p指向的內存空間,徹底地把出局人的位置都清空他就不存在了
p = tmp1->pnext;//下一輪開始的位置
}
printf("\nThe lucky people is %d\n",p->data);//最后的贏家
free(p);//釋放p指向的內存空間
}
int main()
{
int n,m,s;
scanf("%d %d %d",&n,&m,&s);
Node *head = create(n);//調用函數創建含n個節點的循環鏈表
Josephus(head,s,m);//調用模擬Josephus的函數
return 0;
}