国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)-循環(huán)鏈表:處理約瑟夫環(huán)問題

這篇具有很好參考價(jià)值的文章主要介紹了數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)-循環(huán)鏈表:處理約瑟夫環(huán)問題。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

目錄

問題描述

一、基本概念

?1.普通鏈表

2.單向循環(huán)鏈表?

二、問題處理

1.創(chuàng)建鏈表

2.查找

3.刪除

?4.其他

?三.實(shí)驗(yàn)環(huán)節(jié)

四.總結(jié)

問題描述

約瑟夫環(huán)問題的一種描述是:編號為1,2,...,n的n個(gè)人按順時(shí)針方向圍坐一圈,每人持有一個(gè)密碼(正整數(shù))。一開始任選一個(gè)正整數(shù)作為報(bào)數(shù)上限值m,從第一個(gè)人開始按順時(shí)針方向自1開始順序報(bào)數(shù),報(bào)到m時(shí)停止報(bào)數(shù)。報(bào)m的人出列,將他的密碼作為新的m值,從他在順時(shí)針方向上的下一個(gè)人開始重新從1報(bào)數(shù),如此下去,直到所有人全部出列為止。

基本要求:利用鏈表模擬此過程,按照出列的順序印出各人的編號。

一、基本概念

鏈表是一種鏈?zhǔn)酱鎯Φ木€性表,用一組地址任意的存儲單元存放線性表的數(shù)據(jù)元素,稱存儲單元為一個(gè)結(jié)點(diǎn)(節(jié)點(diǎn))。單向循環(huán)鏈表與普通鏈表的區(qū)別在于:普通鏈表的最后一個(gè)鏈表的next指向NULL,而單向循環(huán)鏈表的最后一個(gè)節(jié)點(diǎn)的next指向頭結(jié)點(diǎn)

?1.普通鏈表

循環(huán)鏈表約瑟夫環(huán),鏈表,學(xué)習(xí),數(shù)據(jù)結(jié)構(gòu)

2.單向循環(huán)鏈表?

?循環(huán)鏈表約瑟夫環(huán),鏈表,學(xué)習(xí),數(shù)據(jù)結(jié)構(gòu)

二、問題處理

1.創(chuàng)建鏈表

首先因?yàn)樘幚韱栴}時(shí),鏈表元素的訪問并不是從頭開始的,而是采用“接力棒”的方式進(jìn)行訪問。所以應(yīng)該使用不帶有頭結(jié)點(diǎn)的單向循環(huán)鏈表。

代碼如下:?

typedef struct Data
{
    int number; // 編號
    int code;   // 密碼
    /*
        存放數(shù)據(jù)
    */
} Data;
typedef struct SqList
{
    Data data;    // 數(shù)據(jù)域
    SqList *next; // 指針域
} SqList;

SqList *CreateList(int n) // 生成一個(gè)不帶頭節(jié)點(diǎn)的n個(gè)元素的循環(huán)鏈表
{
    if (n < 1) // 輸入的n不合法
    {
        printf("輸入不合法!");
        system("pause");
        return NULL;
    }
    SqList *end = new SqList; // 尾指針
    for (int i = 1; i < n + 1; i++)
    {
        SqList *newNode = (SqList *)malloc(sizeof(SqList *));
        if (i == 1) // 鏈表為空時(shí)輸入首元節(jié)點(diǎn)的密碼
        {
            newNode->next = newNode;
            cout << "請輸入成員" << i << "的密碼:";
            cin >> newNode->data.code;
            newNode->data.number = 1;
            end = newNode;
            continue;
        }
        // 鏈表不為空時(shí)輸入newNode數(shù)據(jù)的密碼
        cout << "請輸入成員" << i << "的密碼:";
        cin >> newNode->data.code;
        newNode->data.number = i;
        // 尾插法構(gòu)建鏈表
        newNode->next = end->next;
        end->next = newNode;
        end = newNode;
    }
    return end->next;
}

這里需要注意的是因?yàn)榫幪柺怯行虻摹错槙r(shí)針方向,所以采用尾插法。

2.查找

代碼如下:

SqList *ListSearch(SqList *L, int k) // 返回鏈表中的第k個(gè)元素
{
    if (!L || k < 1 || k > ListLength(L)) // 鏈表為空或輸入的k值不合法
    {
        cout << "Error3!" << endl;
        system("pause");
        exit(0);
    }
    for (int i = 0; i < k - 1; i++)
    {
        L = L->next;
    }
    return L;
}

3.刪除

代碼如下:

SqList *ListDelete(SqList *L, int n) // 刪除鏈表L中指定的第n個(gè)元素
{
    if (!L || n < 1) // 鏈表為空或刪除位置不合法
    {
        cout << "Error2!" << endl;
        system("pause");
        exit(0);
    }
    SqList *front = L;
    SqList *temp = nullptr;         // 暫時(shí)儲存要刪除的元素
    for (int i = 0; i < n - 1; i++) // 移動指針到要刪除的位置上
    {
        L = L->next;
    }
    while (front->next != L) // 尋找要刪除的元素前面的一個(gè)元素
    {
        front = front->next;
    }
    front->next = L->next; // 將要刪除的元素移出鏈表
    temp = L;
    L = L->next;
    free(temp); // 釋放內(nèi)存
    return L;
}

因?yàn)椴捎谩敖恿Π簟钡姆绞皆L問元素,需要記住被刪除元素的后一個(gè)元素。所以返回指針類型。

?4.其他

代碼如下:

int ListLength(SqList *L) // 返回鏈表長度
{
    if (!L) // 輸入空鏈表時(shí)報(bào)錯(cuò)并退出函數(shù)
    {
        cout << "Error1!";
        system("pause");
        exit(0);
    }
    SqList *F_Node = L;
    int count = 1; // 因?yàn)椴粠ь^節(jié)點(diǎn)的鏈表,所以非空時(shí)鏈表節(jié)點(diǎn)個(gè)數(shù)至少為1
    while (L->next != F_Node)
    {
        count++;
        L = L->next;
    }
    return count;
}

void ListPrint(SqList *L) // 打印鏈表L中的元素
{
    if (!L)
    {
        return;
    }
    SqList *Node = L;
    do
    {
        if (Node->next == L)
        {
            cout << "成員" << Node->data.number << "的密碼:" << Node->data.code << "\t";
            return;
        }
        cout << "成員" << Node->data.number << "的密碼:" << Node->data.code << "\t";
        Node = Node->next;
    } while (1);
    return;
}


?三.實(shí)驗(yàn)環(huán)節(jié)

整體代碼:

/*
    整個(gè)實(shí)驗(yàn)重要的步驟就是創(chuàng)建、查找、刪除
*/
#include <iostream>
using namespace std;

typedef struct Data
{
    int number; // 編號
    int code;   // 密碼
    /*
        存放數(shù)據(jù)
    */
} Data;
typedef struct SqList
{
    Data data;    // 數(shù)據(jù)域
    SqList *next; // 指針域
} SqList;

SqList *CreateList(int n) // 生成一個(gè)不帶頭節(jié)點(diǎn)的n個(gè)元素的循環(huán)鏈表
{
    if (n < 1) // 輸入的n不合法
    {
        printf("輸入不合法!");
        system("pause");
        return NULL;
    }
    SqList *end = new SqList; // 尾指針
    for (int i = 1; i < n + 1; i++)
    {
        SqList *newNode = (SqList *)malloc(sizeof(SqList *));
        if (i == 1) // 鏈表為空時(shí)輸入首元節(jié)點(diǎn)的密碼
        {
            newNode->next = newNode;
            cout << "請輸入成員" << i << "的密碼:";
            cin >> newNode->data.code;
            newNode->data.number = 1;
            end = newNode;
            continue;
        }
        // 鏈表不為空時(shí)輸入newNode數(shù)據(jù)的密碼
        cout << "請輸入成員" << i << "的密碼:";
        cin >> newNode->data.code;
        newNode->data.number = i;
        // 尾插法構(gòu)建鏈表
        newNode->next = end->next;
        end->next = newNode;
        end = newNode;
    }
    return end->next;
}
int ListLength(SqList *L) // 返回鏈表長度
{
    if (!L) // 輸入空鏈表時(shí)報(bào)錯(cuò)并退出函數(shù)
    {
        cout << "Error1!";
        system("pause");
        exit(0);
    }
    SqList *F_Node = L;
    int count = 1; // 因?yàn)椴粠ь^節(jié)點(diǎn)的鏈表,所以非空時(shí)鏈表節(jié)點(diǎn)個(gè)數(shù)至少為1
    while (L->next != F_Node)
    {
        count++;
        L = L->next;
    }
    return count;
}
void ListPrint(SqList *L) // 打印鏈表L中的元素
{
    if (!L)
    {
        return;
    }
    SqList *Node = L;
    do
    {
        if (Node->next == L)
        {
            cout << "成員" << Node->data.number << "的密碼:" << Node->data.code << "\t";
            return;
        }
        cout << "成員" << Node->data.number << "的密碼:" << Node->data.code << "\t";
        Node = Node->next;
    } while (1);
}

void ListInsert(SqList *L, Data elem, int a) // 向鏈表L中第a個(gè)位置后面插入數(shù)據(jù)elem
{
    for (int i = 0; i < a - 1; i++)
    {
        L = L->next;
    }
    if (!L)
    {
        return;
    }
    SqList *newNode = new SqList;
    newNode->data = elem;
    newNode->next = L->next;
    L->next = newNode;
}

SqList *ListDelete(SqList *L, int n) // 刪除鏈表L中指定的第n個(gè)元素
{
    if (!L || n < 1) // 鏈表為空或刪除位置不合法
    {
        cout << "Error2!" << endl;
        system("pause");
        exit(0);
    }
    SqList *front = L;
    SqList *temp = nullptr;         // 暫時(shí)儲存要刪除的元素
    for (int i = 0; i < n - 1; i++) // 移動指針到要刪除的位置上
    {
        L = L->next;
    }
    while (front->next != L) // 尋找要刪除的元素前面的一個(gè)元素
    {
        front = front->next;
    }
    front->next = L->next; // 將要刪除的元素移出鏈表
    temp = L;
    L = L->next;
    free(temp); // 釋放內(nèi)存
    return L;
}

SqList *ListSearch(SqList *L, int k) // 返回鏈表中的第k個(gè)元素
{
    if (!L || k < 1 || k > ListLength(L)) // 鏈表為空或輸入的k值不合法
    {
        cout << "Error3!" << endl;
        system("pause");
        exit(0);
    }
    for (int i = 0; i < k - 1; i++)
    {
        L = L->next;
    }
    return L;
}

測試數(shù)據(jù):m的初值為20;n=7,7個(gè)人的密碼依次為:3,1,7,2,4,8,4

(正確的出列順序應(yīng)為6,1,4,7,2,3,5)。?

測試如下:

#define N 7 // 約瑟問題中的人數(shù)

int main(void)
{
    SqList *List = CreateList(N);
    int res[N]; // 存放出列順序
    int m, i = 0, code = 0;
    cout << "請輸入初始的正整數(shù)密碼m" << endl;
    cin >> m;
    while (ListLength(List) != 1)
    {
        int k = 0;
        m = m % (N - i);
        // cout << "當(dāng)前m的值是:" << m << endl;
        /*
            注意在這里m的取值是[0,N-i-1],
            而實(shí)際上m應(yīng)該屬于[1,N-i]。
            所以需要對求模后的m進(jìn)行條件判斷
        */
        if (m == 0)        
        {
            k = N - i;
        }
        else
            k = m;
        code = ListSearch(List, k)->data.code;
        res[i] = ListSearch(List, k)->data.number;
        List = ListDelete(List, k); // 返回新的起始訪問位置
        m = code;
        i++;
    }
    res[i] = ListSearch(List, 1)->data.number; //此時(shí)鏈表中僅有一個(gè)元素
    cout << "出列順序?yàn)?";
    for (int i = 0; i < N; i++)
        cout << res[i] << "\t";
    free(List); // 釋放內(nèi)存
    return 0;
}

?循環(huán)鏈表約瑟夫環(huán),鏈表,學(xué)習(xí),數(shù)據(jù)結(jié)構(gòu)

四.總結(jié)

該問題的難點(diǎn)就在于元素的訪問是采取“接力棒”的方式進(jìn)行訪問,需要對循環(huán)鏈表有足夠的的理解,同時(shí)對密碼的處理上也需要小心。對于本次實(shí)驗(yàn)來說,還有許多能改進(jìn)的地方,比如非法輸入的檢測,可以把它包裝成一個(gè)函數(shù),這樣處理的話,代碼會更簡潔并且更容易閱讀。

如有錯(cuò)誤,歡迎在評論區(qū)指正。以上內(nèi)容若涉及侵權(quán)請聯(lián)系作者進(jìn)行刪改。?文章來源地址http://www.zghlxwxcb.cn/news/detail-725042.html

到了這里,關(guān)于數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)-循環(huán)鏈表:處理約瑟夫環(huán)問題的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【數(shù)據(jù)結(jié)構(gòu)與算法】【約瑟夫問題】還在用遞歸?教你用鏈表秒殺約瑟夫

    ?????歡迎光臨???? ??我是蘇澤,一位對技術(shù)充滿熱情的探索者和分享者。???? ??特別推薦給大家我的最新專欄 《數(shù)據(jù)結(jié)構(gòu)與算法:初學(xué)者入門指南》???? 本專欄純屬為愛發(fā)電永久免費(fèi)!?。?這是蘇澤的個(gè)人主頁可以看到我其他的內(nèi)容哦???? 努力的蘇澤 http://su

    2024年02月19日
    瀏覽(18)
  • 數(shù)據(jù)結(jié)構(gòu)—約瑟夫環(huán)問題(C語言版)

    數(shù)據(jù)結(jié)構(gòu)—約瑟夫環(huán)問題(C語言版)

    目錄 首先什么是約瑟夫環(huán) 約瑟夫環(huán)實(shí)現(xiàn)方式 一、創(chuàng)建結(jié)構(gòu)體變量 二、初始化鏈表 三、構(gòu)建循環(huán)鏈表 四、刪除鏈表 ?五、完整代碼及注釋講解 約瑟夫環(huán) 是 循環(huán)鏈表 中的一個(gè)經(jīng)典問題;題目描述:n?個(gè)人圍成一圈,從第一個(gè)人開始報(bào)數(shù),數(shù)到?m?的人出列,再由下一個(gè)人重新

    2024年02月11日
    瀏覽(18)
  • 【數(shù)據(jù)結(jié)構(gòu)與算法】約瑟夫環(huán)(C/C++)

    【數(shù)據(jù)結(jié)構(gòu)與算法】約瑟夫環(huán)(C/C++)

    約瑟夫問題的一種描述是:編號為1,2,…,n的n個(gè)人按順時(shí)針方向圍坐一圈,每人持有一個(gè)密碼(正整數(shù))。一開始任選一個(gè)正整數(shù)作為報(bào)數(shù)上限值m,從第一個(gè)人開始。按順時(shí)針方向自1開始順序報(bào)數(shù),報(bào)到m時(shí)停止報(bào)數(shù)。報(bào)m的人出列,將他的密碼作為新的m值,從他在順時(shí)針方向上

    2024年02月12日
    瀏覽(22)
  • C語言數(shù)據(jù)結(jié)構(gòu)篇——約瑟夫環(huán)的實(shí)現(xiàn)

    C語言數(shù)據(jù)結(jié)構(gòu)篇——約瑟夫環(huán)的實(shí)現(xiàn)

    作者名:Demo不是emo? 主頁面鏈接 : 主頁傳送門 創(chuàng)作初心: 對于計(jì)算機(jī)的學(xué)習(xí)者來說,初期的學(xué)習(xí)無疑是最迷茫和難以堅(jiān)持的,中后期主要是經(jīng)驗(yàn)和能力的提高,我也剛接觸計(jì)算機(jī)1年,也在不斷的探索,在CSDN寫博客主要是為了分享自己的學(xué)習(xí)歷程,學(xué)習(xí)方法,總結(jié)的經(jīng)驗(yàn)等

    2023年04月08日
    瀏覽(21)
  • C語言數(shù)據(jù)結(jié)構(gòu)-用鏈表解決約瑟夫環(huán)問題

    C語言數(shù)據(jù)結(jié)構(gòu)-用鏈表解決約瑟夫環(huán)問題

    只是普通的大學(xué)生一枚,不會很牛的技巧和算法,只是在做數(shù)據(jù)結(jié)構(gòu)作業(yè)中的一點(diǎn)感悟和思考。也不知道自己寫得對不對,有什么意見和建議都可以直接指出來哦,我虛心接受(低頭鞠躬.jpg)...... 試用線性表的鏈表存儲結(jié)構(gòu)來實(shí)現(xiàn)約瑟夫(Josephu)問題。約瑟夫問題如下:設(shè)有

    2024年02月06日
    瀏覽(18)
  • 數(shù)據(jù)結(jié)構(gòu)實(shí)驗(yàn)---順序表的合并---鏈表的基本操作---重點(diǎn)解析約瑟夫問題

    數(shù)據(jù)結(jié)構(gòu)實(shí)驗(yàn)---順序表的合并---鏈表的基本操作---重點(diǎn)解析約瑟夫問題

    實(shí)驗(yàn)的寫法多種多樣,但本文并未采用 #define 定義容量的寫法,這樣寫已經(jīng)是很老舊過時(shí)的寫法。所有實(shí)驗(yàn)主體采用均為動態(tài)開辟,后續(xù)如果利用 C++ 來寫或許會應(yīng)用更多語法… 本篇展示數(shù)據(jù)結(jié)構(gòu)的兩個(gè)實(shí)驗(yàn) 其中,重點(diǎn)分析約瑟夫問題 實(shí)驗(yàn)中代碼的命名風(fēng)格等均與下方博客

    2024年02月16日
    瀏覽(33)
  • 數(shù)據(jù)結(jié)構(gòu)上機(jī)實(shí)驗(yàn)——棧和隊(duì)列的實(shí)現(xiàn)、棧和隊(duì)列的應(yīng)用、進(jìn)制轉(zhuǎn)換、約瑟夫環(huán)問題

    數(shù)據(jù)結(jié)構(gòu)上機(jī)實(shí)驗(yàn)——棧和隊(duì)列的實(shí)現(xiàn)、棧和隊(duì)列的應(yīng)用、進(jìn)制轉(zhuǎn)換、約瑟夫環(huán)問題

    ??1.利用棧的基本操作實(shí)現(xiàn)將任意一個(gè)十進(jìn)制整數(shù)轉(zhuǎn)化為R進(jìn)制整數(shù)。 ??2.利用循環(huán)隊(duì)列實(shí)現(xiàn).約瑟夫環(huán)問題:已知n個(gè)人(以編號1,2,3…n分別表示)圍坐在一張圓桌周圍。從編號為k的人開始報(bào)數(shù),數(shù)到k的那個(gè)人出圈;他的下一個(gè)人又從1開始報(bào)數(shù),數(shù)到k的那個(gè)人出圈;依

    2024年02月08日
    瀏覽(26)
  • C語言---數(shù)據(jù)結(jié)構(gòu)實(shí)驗(yàn)---順序表的合并---鏈表的基本操作---重點(diǎn)解析約瑟夫問題

    C語言---數(shù)據(jù)結(jié)構(gòu)實(shí)驗(yàn)---順序表的合并---鏈表的基本操作---重點(diǎn)解析約瑟夫問題

    實(shí)驗(yàn)的寫法多種多樣,但本文并未采用 #define 定義容量的寫法,這樣寫已經(jīng)是很老舊過時(shí)的寫法。所有實(shí)驗(yàn)主體采用均為動態(tài)開辟,后續(xù)如果利用 C++ 來寫或許會應(yīng)用更多語法… 本篇展示數(shù)據(jù)結(jié)構(gòu)的兩個(gè)實(shí)驗(yàn) 其中,重點(diǎn)分析約瑟夫問題 實(shí)驗(yàn)中代碼的命名風(fēng)格等均與下方博客

    2024年02月16日
    瀏覽(96)
  • 循環(huán)鏈表解決約瑟夫環(huán)問題

    循環(huán)鏈表解決約瑟夫環(huán)問題

    n 個(gè)人圍成一圈,從第一個(gè)人開始報(bào)數(shù),數(shù)到 m 的人出列,再由下一個(gè)人重新從 1開始報(bào)數(shù),數(shù)到 m 的人再出圈,依次類推,直到所有的人都出圈,請輸出依次出圈人的編號。 n個(gè)人圍成一圈,很容易可以想到用循環(huán)鏈表解決問題,用結(jié)點(diǎn)代表每個(gè)人,節(jié)點(diǎn)的數(shù)據(jù)域存儲人的編號

    2024年02月07日
    瀏覽(27)
  • 約瑟夫死者游戲-C語言實(shí)現(xiàn)-雙向循環(huán)鏈表

    設(shè)計(jì)題目 1 : 約瑟夫生者死者游戲 [問題描述]: 約瑟夫生者死者游戲的大意是: 30 個(gè)旅客同乘一條船,因?yàn)閲?yán)重超載,加上風(fēng)高浪大, 危險(xiǎn)萬分;因此船長告訴乘客,只有將全船一半的旅客投入海中,其余人才能幸免遇難。無 奈,大家只得同意這種辦法,并議定 30 個(gè)人圍

    2024年02月03日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包