1. 程式人生 > >資料結構程式設計——約瑟夫雙向生死殺人遊戲

資料結構程式設計——約瑟夫雙向生死殺人遊戲

首先是主函式:

/**
*版權所有(C)2017,ShangWenZhe
*
*檔名稱:main.cpp
*檔案標識:無
*內容摘要:本檔案的作用是呼叫演算法庫裡面的函式,完成題目要求。
*其它說明:無
*當前版本:V1.0
*作者:尚文哲
*完成日期:2017,12,15
**/

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"Jd.h"

int main()
{
int total = 30;//總人數
int target = 15;//目標保留的人數
int forward = 9;//正向位移數
int reverse = 5;//反向位移數
find(creat(total), total, forward, reverse, target);
return 0;
system("pause");
}
接下來是標頭檔案:
/**
*版權所有(C)2017,Shangwenzhe。
*
*檔名稱:Jd.h
*檔案標識:無
*內容摘要:本檔案的作用是宣告節點的結構,還有需要用到的函式。
*其它說明:無
*當前版本:V1.0
*作者:尚文哲
*完成日期:2017,12,15
**/

#ifndef JD_H_INCLUDED
#define JD_H_INCLUDED


typedef struct Node
{
    int num;//用於儲存當前序號
    struct Node *next;//下一個節點指標
    struct Node *previous;//上一個節點指標
}
LinkList;

LinkList *create(int n);//建立連結串列
void find(LinkList *l, int total, int forward, int reverse, int target);//查詢到人之後刪除。


#endif // JD_H_INCLUDED
最後是標頭檔案的實現:
/**
*版權所有(C)2017,Shangwenzhe
*
*檔名稱:Jd.cpp
*檔案標識:無
*內容摘要:本檔案的作用是實現.h檔案裡面的函式。
*其它說明:無
*當前版本:V1.0
*作者:尚文哲
*完成日期:2017,12,15
**/
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
#include"Jd.h"

/**

*功能描述:建立雙向迴圈連結串列的資料結構。

*輸入引數:要建立的連結串列的長度n。

*輸出引數:無。

*返回值:head。

*其他說明:先連結中間節點,後連結頭尾節點。

**/
LinkList *create(int n)
{
    //建立頭結點
    int i = 1;
    LinkList *now, *tail, *head;
    head = (LinkList *)malloc(sizeof(LinkList));//為頭結點在記憶體中申請空間
    head->num = i;//為頭結點賦值
    tail = head;//因為只有一個節點,所有頭結點、尾節點都指向相同的節點
    for (i = 2; i <= n; i++)
    {
        now = (LinkList *)malloc(sizeof(LinkList));//為新建節點在記憶體中申請空間
        now->num = i;//為新建的節點賦值
        tail->next = now;//當前尾節點指向下一個節點的指標指向新建立的節點
        now->previous = tail;//讓新建立的節點的指向上一個節點的指標指向當前的尾節點
        tail = now;//讓新建的節點成為新的尾節點
    }
    //成環
    tail->next = head;//最終的尾節點的下一個指標指向頭結點
    head->previous = tail;//頭結點的上一個指標指向尾節點
    return head;//返回頭結點的地址
}

/**

*功能描述:找到應該刪除的人並且刪除,每次刪除一個人,其中有3個選項可供選擇,分別是(1)刪除節點
            (2)增添節點並繼續刪除,(3)刪除指定節點並且繼續刪除按要求刪除。

*輸入引數:第一個是連結串列的頭節點,第二個是當前人數,第三個是順時針計數的人數,第四個是逆時針計數
*的人數,最後一個是目標人數。

*輸出引數:無。

*返回值:無。

*其他說明:每次執行都刪除一個人,若是輸入的數不在介面顯示的範圍內則預設執行刪除操作。

**/
void find(LinkList *l, int total, int forward, int reverse, int target)
{
    int i = 0;//控制正反方向翻轉:0是正向,1是反向
    LinkList *now;//當前節點(要被殺的人)
    now = l;
    while (total > target)//若當前總人數多於目標人數則繼續進行
    {
        //正向
        if (i == 0)
        {
            //當前節點指標正向位移forward個
            for (int index = 1; index < forward; index++)
            {
                now = now->next;

            }
            i = 1;//方向翻轉

        }
        //反向
        else
        {
            //當前節點反向位移reverse個
            for (int index = 1; index < reverse; index++)
            {
                now = now->previous;
            }
            i = 0;//方向翻轉
        }
        if (l == now)
        {
            l = now->next;
        }
        printf("%d \n", now->num);//控制檯列印當前指標指向的值(殺掉當前指標指向的人)
        now->previous->next = now->next;//讓當前指標指向的節點的上一個節點的下一節點指標指向當前節點的下一個節點
        now->next->previous = now->previous;//讓當前指標指向的節點的上一節點的指標指向當前節點的上一個節點
        total--;//總人數減一



        LinkList *all = l;
        //輸出所有的num。
        for (int i = 0; i < total; i++)
        {
            printf("%d ", all->num);
            all = all->next;
        }
        printf("\n");


        int order = 0;//用來存放命令的。
        printf("\t\t1:kill one\t2:add one\t3:remove one\n");//輸出提示
        scanf("%d", &order);//讀入
        //printf("%d", order);//輸出
        if (2 == order)//當輸入的值為2時。執行以下迴圈。
        {
            printf("please enter the new number to add:");
            int num = 0;
            scanf("%d", &num);
            LinkList *add = (LinkList *)malloc(sizeof(LinkList));//為新建節點在記憶體中申請空間
            add->num = num;//給新開闢的記憶體空間放入資料域num。
            //以下是往連結串列裡新增新的節點(位置是now後面)。
            add->next = now->next;//令add的後繼指標等於now的後繼指標。
            now->previous->next = add;//令now的前一個節點的後繼指標指向add。
            add->previous = now->previous;//令add的前驅指標指向now的前驅指標。
            now->next->previous = add;//令now的後一個元素的前驅指標指向add。
            now = add;//更新now值。
            total++;//總人數+1
        }
        else if (3 == order)//當輸入的是3的時候執行以下迴圈。功能是刪除一個人(刪除位置是now位置上的節點)。
        {
            LinkList  *s;
            s=now;
            printf("please enter the  number that you want to move:");
            int numss = 0;
            scanf("%d", &numss);
            //找出想要刪除的元素位置並令s指向它。
            while(s->next!=now)
            {
                if(s->num==numss)//如果在查詢中發現了相等的元素立即跳出while迴圈。
                    break;
                s=s->next;
            }
            //接下來是完成刪除該節點的操作
            s->next->previous=s->previous;//讓該節點的後繼節點的前驅指標指向其前驅結點。
            s->previous->next=s->next;//讓該節點的前驅節點的後繼指標指向該節點的後繼節點。
            total--;//總數減一。

        }



        printf("********************************************\n");
        all = l;
        //輸出更改後的num;
        for (int i = 0; i < total; i++)
        {
            printf("%d ", all->num);
            all = all->next;
        }
        printf(" \n");

    }
}

最後執行結果:



以下是自動刪除的實現:


以下是增添並刪除:


以下是刪除指定元素並且按順序自動刪除:


以上就是程式設計的程式碼。