代码改变世界

数据结构学习中的简单问题(二):用循环链表求解简单约瑟夫问题

2013-04-11 00:52  liuzq2013  阅读(351)  评论(0)    收藏  举报

头文件:CircList.h

template <class T>
struct CircLinkNode {       //循环链表结点类定义!!
     T data;
     CircLinkNode<T> *link;
     CircLinkNode ( CircLinkNode<T> *next = NULL ) { link = next; }    //构造函数不带数据
     CircLinkNode ( T d, CircLinkNode<T> *next = NULL ) { data = d;  link = next; }  //带数据
     bool operator==(T x) { return data == x; } 
     bool operator!=(T x) { return data != x; }
};

template <class T>      //循环链表(不带表头结点)类定义
class CircList{
    private:
        CircLinkNode<T> *first, *last;//how to deal the relationship between these two nodes?  //头指针, 尾指针
    public:                             //增加备用尾指针便于操作
        CircList(const T x)
        {
            first=new CircLinkNode<T>(x);
            first->link=first;
            last=first;
        }
        //CircList(CircList<T>& L);        //复制构造函数
        ~CircList(){}                     //析构函数
        bool IsEmpty() { return (first == NULL)?true:false; }
        int Length()             //计算链表长度
        {
            if(IsEmpty()){return 0;}
            CircLinkNode<T>* cur=first;
            int count=1;
            while(cur->link!=first){
                cur=cur->link;
                count++;
            }
            return count;
        }
        //bool IsEmpty() { return (first == NULL)?true:false; }
        CircLinkNode<T> *getHead() const {return first;}  //*
        CircLinkNode<T> *Search ( T& x )    //搜索
        {
            if(IsEmpty()){return NULL;}
            CircLinkNode<T>* cur=first;
            while(cur->link!=first){
                if(cur->data==x){return cur;}
                cur=cur->link;
            }
            return NULL;
        }
        CircLinkNode<T> *Locate ( int i )        //定位
        {
            int len=Length();
            if(i<1||i>len) return NULL;
            CircLinkNode<T>* cur=first;
            for(int j=1;j<i;j++){
                cur=cur->link;
            }
            return cur;
        }
        bool getData (int i, T& x )
        {
            if(i<1||i>Length()){return false;}
            CircLinkNode<T>* cur=Locate(i);
            x=cur->data;
            return true;
        }
        //void setData ( int i, T& x );               //修改
        bool Insert ( int i, T& x )                      //插入
        {
            if(i<0||i>Length()) return false;
            CircLinkNode<T>* newNode=new CircLinkNode<T>(x);
            if(IsEmpty()){
                first=new CircLinkNode<T>(x);
                first->link=first;
                last=first;
                return true;
            }
            if(i==0){
                newNode->link=first;
                first=newNode;
                last->link=first;
            }
            else if(i==Length()){
                if(Length()>1){
                    newNode->link=first;
                    last->link=newNode;
                    last=newNode;//although last is moved to newNode, the privious last node is still existing!
                }
                else{
                    newNode->link=first;
                    first->link=newNode;
                    last=newNode;
                }
            }
            else{
                CircLinkNode<T>* cur=Locate(i);
                newNode->link=cur->link;
                cur->link=newNode;
            }
            return true;
        }
        bool Remove ( int i, T& x)                      //删除
        {
            if(i<1||i>Length()||IsEmpty()) return false;
            CircLinkNode<T>* del=first;
            if(i==1){
                first=del->link;
                last->link=first;
                x=del->data;
                return true;
            }
            else{
                CircLinkNode<T>* cur=Locate(i-1);
                del=cur->link;
                cur->link=del->link;
                x=del->data;
                delete del;
                return true;
            }
        }
};

主程序:

#include <iostream>

#include "CircList.h"

using namespace std;



int main()

{

    int n,m;

    cin>>n>>m;

    CircList<int>* L=new CircList<int>(1);

    for(int i=n;i>1;i--){

        L->Insert(1,i);

    }

    cout<<(L->Length())<<endl;

    CircLinkNode<int>* p=L->getHead(),*pre=NULL;

    for (int i = 0; i < n-1; i++ ) {         //执行n-1次

        for (int j = 1; j < m; j++)         //数m-1个人

        { 

            pre = p;  p = p->link; 

        }

        cout <<"出列的人是"<< p->data << endl;

        pre->link = p->link;

        delete p;

        p = pre->link;

    }

    return 0;

}

原本以为对循环语句的使用已经很熟练了,没想到自己写主程序一开始竟然出了问题,暂时用标准版本的循环。