日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

问题 C: 【例2-3】围圈报数

發(fā)布時(shí)間:2023/12/4 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 问题 C: 【例2-3】围圈报数 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目描述

有n(n<100)個(gè)人依次圍成一圈,從第1個(gè)人開(kāi)始報(bào)數(shù),數(shù)到第m個(gè)人出列,然后從出列的下一個(gè)人開(kāi)始報(bào)數(shù),數(shù)到第m個(gè)人又出列,…,如此反復(fù)到所有的人全部出列為止。設(shè)n個(gè)人的編號(hào)分別為1,2,…,n,打印出列的順序。

輸入

n和m。

輸出

出列的順序。

樣例輸入

4 17

樣例輸出

1 3 4 2

我們可以看到這個(gè)圍圈報(bào)數(shù)(即約瑟夫問(wèn)題),其實(shí)就是鏈表問(wèn)題。我們通過(guò)這道題需要掌握的是循環(huán)單鏈表的寫(xiě)法(以c語(yǔ)言為例)

一、循環(huán)鏈表的寫(xiě)法

1.先定義鏈表的結(jié)構(gòu)體

struct child{int data;struct child* next; };

然后再全局變量定?“頭節(jié)點(diǎn)”和“約瑟夫環(huán)的兩個(gè)參數(shù)”

struct child* headnode; int n,m;

下面,我們來(lái)定義兩個(gè)函數(shù),分別是“創(chuàng)建空節(jié)點(diǎn)”與“創(chuàng)建有數(shù)據(jù)的節(jié)點(diǎn)”

struct child* emptynode(){struct child* p = (struct child*)malloc(sizeof(struct child));p->data = NULL;p->next = NULL;return p; }struct child* createnode(int num){struct child* p = (struct child*)malloc(sizeof(struct child));p->data = num;p->next = NULL;return p; }

我們可以看出這兩段代碼的主要差別,其實(shí)就是p->data=NULL和p->data=num

接下來(lái)定義一個(gè)函數(shù)“createlistBytail”,以尾接法,創(chuàng)建循環(huán)單鏈表

void createlistBytail(struct child* headnode,int num){struct child* r=headnode;for (int i=2; i<=num; i++ ){struct child* s = createnode(i);s->next = r->next;r->next = s;r=s;} r->next = headnode; }

其中需要注意的是,這段代碼看似為單純的創(chuàng)建單鏈表,其實(shí)我們?cè)诮Y(jié)尾處添加了一段代碼

r->next = headnode;

這段代碼保證了單鏈表的循環(huán),也正因?yàn)檫@段代碼,使得我們的單鏈表成功升級(jí)為循環(huán)單鏈表!

當(dāng)然,為了檢驗(yàn)我們的鏈表是否創(chuàng)建成功,我們可以寫(xiě)入這列代碼,來(lái)遍歷出鏈表的數(shù)據(jù)

void printlist(struct child* headnode){struct child* pMove = headnode;while(pMove) {printf("%d",pMove->data );pMove = pMove->next ;} }

?接下來(lái),我們開(kāi)始創(chuàng)建solve函數(shù),實(shí)現(xiàn)圍圈報(bào)數(shù)功能

void solve(struct child* headnode,int n,int m){int i,j;struct child* p;struct child* q;for(i=1;i<=n;i++){p = headnode;j = 1;for(j=1;j<m-1;j++){p = p->next ;}q = p->next ;printf("%d ",q->data );p->next = q->next ;headnode = p->next ;} }

其中,我們需要注意的是?我們?cè)谶M(jìn)行第二個(gè)for循環(huán)時(shí),j<m-1這個(gè)數(shù)值不要搞錯(cuò)。我們?yōu)槭裁匆猨<m-1呢?因?yàn)槲覀円WCp是在第m個(gè)人的前一個(gè)人,這樣我們就可以使q指向p->next,也就是我們想要的那個(gè)第m個(gè)人,實(shí)現(xiàn)精準(zhǔn)查找,然后精準(zhǔn)“刪除”。但是問(wèn)題來(lái)了,我們?yōu)槭裁床恢苯訉指向第m個(gè)人呢,這樣我們直接輸出p不就好了么:(。非也非也!你只是想到了輸出數(shù)值的事,但是后面的事你卻沒(méi)能想到。

我們?cè)谶@段函數(shù)的主要任務(wù)是什么呢?1.輸出第m個(gè)人2.刪除m,讓m前一個(gè)人接上m后一個(gè)人3.將領(lǐng)頭人headnode變成m的下一個(gè)人,也就是說(shuō)從m的下一個(gè)人開(kāi)始報(bào)數(shù)。這樣我們不難發(fā)現(xiàn)我們將p設(shè)為m的前一個(gè)人,是要將p-next指向q->next,實(shí)現(xiàn)刪除m的目的,因?yàn)槲覀児?jié)點(diǎn)的指針能指向某節(jié)點(diǎn)的后面,卻指向不了節(jié)點(diǎn)的前面,所以哦我們需要這樣的一個(gè)p指向m前一個(gè)點(diǎn)。

最后,我們編寫(xiě)主函數(shù),將上面的函數(shù)包裝進(jìn)去

其中我們要注意的是,創(chuàng)建空節(jié)點(diǎn)與數(shù)據(jù)節(jié)點(diǎn)不在主函數(shù)里。

int main(){struct child* headnode = createnode(1);scanf("%d %d",&n,&m);createlistBytail(headnode,n);//printlist(headnode);solve(headnode,n,m);return 0; }

這樣,我們的代碼就算結(jié)束了。最后,給大家奉上“圍圈報(bào)數(shù)”(即約瑟夫問(wèn)題)的完整版代碼

#include<stdio.h> #include<stdlib.h> struct child{int data;struct child* next; };struct child* headnode; int n,m;struct child* emptynode(){struct child* p = (struct child*)malloc(sizeof(struct child));p->data = NULL;p->next = NULL;return p; }struct child* createnode(int num){struct child* p = (struct child*)malloc(sizeof(struct child));p->data = num;p->next = NULL;return p; }void createlistBytail(struct child* headnode,int num){struct child* r=headnode;for (int i=2; i<=num; i++ ){struct child* s = createnode(i);s->next = r->next;r->next = s;r=s;} r->next = headnode; }void printlist(struct child* headnode){struct child* pMove = headnode;while(pMove) {printf("%d",pMove->data );pMove = pMove->next ;} }void solve(struct child* headnode,int n,int m){int i,j;struct child* p;struct child* q;for(i=1;i<=n;i++){p = headnode;j = 1;for(j=1;j<m-1;j++){p = p->next ;}q = p->next ;printf("%d ",q->data );p->next = q->next ;headnode = p->next ;} }int main(){struct child* headnode = createnode(1);scanf("%d %d",&n,&m);createlistBytail(headnode,n);//printlist(headnode);solve(headnode,n,m);return 0; }

?

?

?

?

總結(jié)

以上是生活随笔為你收集整理的问题 C: 【例2-3】围圈报数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。