zoukankan      html  css  js  c++  java
  • 【数据结构】1-2 约瑟夫环问题

    这里放出两种不同的代码,一个是老师给的(较为复杂),还有一个是自己写的。

    自己写的:

    #include<iostream>
    using namespace std;
    struct Node {
        int data;            //数据单元
        Node *link;            //指向下一个结点
    };
    class Josephus
    {
    private:
        Node *head, *current;        //head是头结点,current指向当前结点
        int sum;//存储链表中元素的个数
    public:
        Josephus();                //无参构造函数,全部初始化为空
        Josephus(int Snumber, int strnumber);//有参构造函数,Snumber为总数,strnumber为开始序号
        ~Josephus();//析构函数
        void del(Node *&p);
        void select(int num);//num为间隔数
        void print();
    };
    Josephus::Josephus()
    {
        current = NULL;
        head = NULL;
        sum = 0;
    }
    Josephus::Josephus(int Snumber, int strnumber)
    {
        sum = Snumber;
        head = new Node;
        head->data = strnumber;
        current = head;
        int dt = strnumber + 1;
        for (int i = 1; i < Snumber; i++)
        {
            Node *p;
            p = new Node;
            p->data = dt;
            current->link = p;
            current = p;
            dt++;
        }
        current->link = head;
    
    }
    void Josephus::del(Node *&p)
    {
        Node *d = p->link;
        p->link = p->link->link;
        delete d;
    }
    void Josephus::select(int num)
    {
        int sont = 1;
        Node *p = head;
        while (sum!= 1)
        {
            if (sont % (num-1)  == 0)
            {
                del(p);
                sum--;
                head = p;
            }
            sont++;
            p = p->link;
        }
        
        
    }
    void Josephus::print()
    {
        cout << "剩下的序号有:" << endl;
        Node *p = head;
        for (int i = 0; i < sum; i++)
        {
            cout << p->data << " ";
            p = p->link;
        }
        cout << endl;
    }
    Josephus::~Josephus()
    {
        /*Node *p = head->link;
        while (p!=head)
        {
            Node *de = p;
            p = p->link;
            delete de;
        }*/
        head = NULL;
        current = NULL;
    }

    测试代码:

    #include"LinkList.h"
    int  main()
    {
        int Snum, stnum,num;
        cout << "请输入总数以及开始序号:";
        cin >> Snum >> stnum;
        Josephus A(Snum, stnum);
        A.print();
        cout << "请输入间隔数:";
        cin >> num;
        A.select(num);
        A.print();
        system("pause");
        return 0;
    }

    其实原理很简单,就是通过循环链表不断循环然后删除就OK

    标准代码:

    //Circle.h
    #include<iostream>
    using namespace std;
    template<class T>
    struct Node   //结点结构
    {
        T data;   //结点数据
        Node*link;
        Node() { link = NULL; }
        Node(T e, Node*next = NULL)
        {
            data = e;
            link = next;
        }
    };
    template<class T>
    class CircleLinkList
    {     //不带表头结点的循环链表类
    private:
        Node<T> *current, *front; //current指向某结点,front指向current前驱
    public:
        CircleLinkList() :current(NULL), front(NULL) {} //构建空循环链表
        CircleLinkList(T *d, int  mSize); //利用d数组元素构建循环链表
        ~CircleLinkList();            //析构函数
        bool InsertAfter(const T&x);    //在current所指结点之后插入x
        bool RemoveCurrent(T&x);    //删除current所指结点
        void movenext(int n = 1);    //current后移n次
        T GetCurrentData() { return current->data; }
        bool toLocatioin(T &t);//让current指向t结点,若没有则current不移动
        void Output() const;    //输出循环链表
    };  
    class Joseph //    约瑟夫环类
    {
    private:
        int numOfBoy;  //圈中人数
        int startPosition;  //报数起始点
        int interval;     //报数间隔
    public:
        Joseph(int boys, int start, int m) :
            numOfBoy(boys), startPosition(start), interval(m) {}//构造函数
        void setNumOfBoy(int num) { numOfBoy = num; }//重置圈中人数
        void setStartPosition(int start) { startPosition = start; }//重置起始点
        void setInterval(int inter) { interval = inter; }//重置报数间隔
        int GetWinner();//求得最终优胜者编号
        void print();   //输出约瑟夫环
    };
    template<class T>
    CircleLinkList<T>::CircleLinkList(T *d, int  mSize)
    {    //构造函数,将d数组中的mSize个元素创建循环链表
    //采用前插法创建。
        int i;
        Node<T> *p;
        current = new Node<T>;
        current->data = d[mSize - 1];
        front = current;
        for (i = mSize - 2; i >= 0; i--)
        {
            p = new Node<T>(d[i], current);
            current = p;
        }
        front->link = current;
    }
    template<class T>
    CircleLinkList<T>::~CircleLinkList()    //析构函数
    {
        while (current != front)//销毁循环链表
        {
            Node<T> *r = current;
            current = current->link;
            delete r;
        }
        delete current;
    }
    template<class T>
    bool CircleLinkList<T>::InsertAfter(const T&x)
    //在current所指结点之后插入x,current指向x结点
    {
        Node<T> *s = new Node<T>(x);
        if (!s)return false;
        if (!current)  //原循环链表为空
            current = front = s->link = s;
        else //原循环链表非空
        {
            s->link = current->link;
            current->link = s;
            front = current;
            current = s;
        }
        return true;
    }
    template<class T>
    bool CircleLinkList<T>::RemoveCurrent(T&x) //删除current所指结点
    {
        if (!current)//循环链表为空
            return false;
        x = current->data;
        if (current == front)//链表中只有一个元素
        {
            delete current;
            current = front = NULL;
        }
        else
        {
            front->link = current->link;//修改链表指针
            delete current;
            current = front->link;
        }
        return true;
    }
    template<class T>
    void CircleLinkList<T>::Output() const     //输出循环链表
    {
        if (!current)//循环链表为空
            return;
        Node<T> *p = current;
        do
        {
            cout << p->data << "  ";
            p = p->link;
        } while (p != current);
        cout << endl;
    }
    template<class T>
    void CircleLinkList<T>::movenext(int k)    //current后移k次
    {
        for (int i = 1; i <= k; i++)
        {
            front = current; // front后移
            current = current->link; //current后移
        }
    }
    template<class T>
    bool CircleLinkList<T>::toLocatioin(T &t)
    //将current指向元素为t的结点,若没有则current不移动
    {
        if (!current)//循环链表为空
            return false;
        Node<T> *current1 = current, *front1 = front;
        while (current1->data != t) //寻找元素t
        {
            front1 = current1;
            current1 = current1->link;
            if (current1 == current)// 已寻找一圈没有元素为t的结点
                return false;
        }
        current = current1; //current指向元素为t的结点
        front = front1;
        return true;
    }
    int Joseph::GetWinner()//获得最终优胜者
    {
        CircleLinkList<int> boys;
        for (int i = 0; i < numOfBoy; i++)//创建循环链表,编号依次为1~numOfBoy
        {
            int temp = i + 1;
            boys.InsertAfter(temp);
        }
        boys.toLocatioin(startPosition);   //找到报数起点
        cout << endl << "依次出列的小孩是:" << endl;
        for (int i = 1; i < numOfBoy; i++)   //numOfBoy-1个小孩出圈
        {
            int x;
            boys.movenext(interval - 1);  //报数
            boys.RemoveCurrent(x); //出圈
            cout << x << "  ";  //输出出圈编号
        }
        return boys.GetCurrentData();  //返回优胜者编号
    }
    void Joseph::print()   //输出约瑟夫环
    {
        cout << "圈中人数:" << numOfBoy << endl;
        cout << "报数起始点:" << startPosition << endl;
        cout << "报数间隔:" << interval << endl;
    }

    测试代码

    //测试代码.cpp
    #include"Circle.h"
    int main()
    {
        int total, interv, startboy;
        cout << "请分别输入人数,起始号码和间隔数"<<endl;
        cin >> total >> startboy >> interv;
        Joseph jose(total, startboy, interv);
        jose.print();
        cout << "优胜者编号为: " << jose.GetWinner() << endl;
        system("pause");
        return 0;
    }
  • 相关阅读:
    转载:使用单独的log4net类
    反射方法
    log4net 的配置问题和使用扩展的TGLOG.DLL
    office2010 x64 Retrieving the COM class factory for component with CLSID {000209FF00000000C000000000000046} failed due to the following error: 800
    sharepoint2013 错误2
    sp2013版本区别
    sps2013安装错误
    发光动画
    关于html5缓存部分比较详细的说明
    httpmodule sharepoint
  • 原文地址:https://www.cnblogs.com/robotpaul/p/9978017.html
Copyright © 2011-2022 走看看