数据结构程序设计——约瑟夫双向生死杀人游戏

首先是主函数:

/**
*版权所有(C)2017,ShangWenZhe
*
*文件名称:main.cpp
*文件标识:无
*内容摘要:本文件的作用是调用算法库里面的函数,完成题目要求。
*其它说明:无
*当前版本:V1.0
*作者:尚文哲
*完成日期:2017,12,15
**/

#include
#include
#include
#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
#include
#include
#include
#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");

    }
}


最后运行结果:



以下是自动删除的实现:


数据结构程序设计——约瑟夫双向生死杀人游戏_第1张图片

以下是增添并删除:

数据结构程序设计——约瑟夫双向生死杀人游戏_第2张图片


以下是删除指定元素并且按顺序自动删除:

数据结构程序设计——约瑟夫双向生死杀人游戏_第3张图片


以上就是程序设计的代码。

你可能感兴趣的:(数据结构程序设计——约瑟夫双向生死杀人游戏)