1. 程式人生 > >約瑟夫環--迴圈連結串列的應用

約瑟夫環--迴圈連結串列的應用

     通過迴圈連結串列實現約瑟夫環

  • 要求:1)要求設計一個程式模擬次過程,輸入總的人數n,所報的出列的數字k,計數開始的位置p;
  • 程式所能達到的功能:構造連結串列;輸入資料;執行報數;儲存出列人的序號,刪除出列人的資訊以及把指向出列人的指標移到出列人的下一個人,然後重新開始執行報數;直到最後一個人報數完畢,程式結束。
  • 測試資料:n=9,9個人的序號分別為:1,2,3,4,5,6,7,8,9。然後p=1,從第一個開始報數。k=5,則確定輸出的序列為:5,1,7,4,3,6,9,2,8。

例:   41個人從1開始報數,報到3的出列,則最後剩下的是31號

程式碼如下:

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;

typedef struct Node
{
    int num;
    struct Node *next;
} LinkList;

LinkList *creat(int n)
{
    LinkList *p, *q, *head;
    int i = 1;
    p = (LinkList *)malloc(sizeof(LinkList));
    p->num = i;
    head = p;
    for (i = 2; i <= n; i++)
    {
        q = (LinkList *)malloc(sizeof(LinkList)); /*Malloc()向系統申請分配指定size個位元組的記憶體空間。返回型別是 void* 型別。void* 表示未確定型別的指標。C,C++規定,void* 型別可以強制轉換為任何其它型別的指標。*/
        q->num = i;
        p->next = q;
        p = q;
    }
    p->next = head;        /*使連結串列尾指向連結串列頭 形成迴圈連結串列*/
    return head;
}

void fun(LinkList *L, int pos, int cnt)
{
    int i;
    LinkList *p, *s, *q;
    p = L;
    printf("出列順序為:");
    while (p->next != p)
    {
        for (i = 1; i < cnt; i++) /*從1開始*/
        {
            q = p;
            p = p->next;
        }
        printf("%5d", p->num);
        s = p;
        q->next = p->next;
        p = p->next; /*使p指向新的起點*/
        free(s);/*free()與malloc()函式配對使用,釋放malloc函式申請的動態記憶體*/
    }
    printf("%5d\n", p->num);
}

int main()
{
    LinkList *L;
    int n;
    cin>>n;
    int pos;
    cin>>pos;//從pos開始報數
    int cnt;//報到cnt的出列
    cin>>cnt;

    L = creat(n);
    fun(L, pos,cnt);

    return 0;
}