关于约瑟夫环的一些漏洞

#include <iostream>
using namespace std;

typedef struct
{
    int number; //结点的密码
    int position; //结点的位置
}data;

typedef struct LNode
{
    data point;
    struct LNode *next;
}LNode,*Linklist;

int main()
{
    Linklist l;
    l=new LNode;
    l->next=NULL;//头指针的建立

    Linklist r;
    r=new LNode;
    r=l;        //建立尾指针,后插法顺序插入链表

    int n;
    cout <<"请输入链表的长度:";
    cin>>n;

    cout <<"请输入"<<n<<"个整数:"<<endl;//链表的建立
    for(int i=1;i<=n;i++)  
    {
        Linklist p;
        p=new LNode;
        cin>>p->point.number;
        p->point.position=i;
        p->next=NULL;
        r->next=p;
        r=p;
        if(i==n)
        {
            p->next=l->next;   //循环链表的建立,最后一个结点越过头指针指向首结点
        }
    }

    int m;
    cout <<"请输入设定的上限数:";
    cin>>m;

    Linklist p;//验证是否可以循环输出,即循环链表是否建立成功
    p=new LNode;
    p=l->next;  //将p设为首结点
    for(int i=1;i<=m;i++) //利用输出判定循环链表的建立
    {
        cout <<p->point.number<<p->point.position<<"  ";
        p=p->next;
    }
    cout <<endl;
    p=l->next;  //循环完成后把p的位置还原

    int t=0;//t代表执行的次数
    for(int i=1;i<=m;i++)//利用给出的上限数开始循环 依次输出密码的位置
    {
        while(m==1)    //防止输入的上限数太小导致循环停止
        {
            i=0;    //设置i归零,从新开始循环
            m=p->next->point.number;
            cout<<p->next->point.position<<"  ";
            t++;
            Linklist w;
            w=new LNode;
            w=p->next;
            p->next=w->next;
            delete w;
        }
        if(i==m-1)
        {
            i=0;  //设置i归零,从新开始循环
            m=p->next->point.number;
            cout <<p->next->point.position<<"  ";
            t++;
            Linklist q;
            q=new LNode;
            q=p->next;
            p->next=q->next;
            delete q;
            while(m==1)    //防止密码太小导致循环停止
            {
                i=0;  //设置i归零,从新开始循环
                m=p->next->point.number;
                cout<<p->next->point.position<<"  ";
                t++;
                Linklist w;
                w=new LNode;
                w=p->next;
                p->next=w->next;
                delete w;
            }
        }
        p=p->next;
        if(t==n-1)   //判断是否只剩下一个结点,若剩下一个则结束循环
        {
            break;
        }
        
    }
    cout <<p->point.position<<endl;  //输出最后一个结点的位置

    return 0;
}

以上是修正过后的代码

1.对于输出验证循环列表成立后没有把p指针重新指向首元节点

2.没有判断输入的上限数的值是否太小,可能导致循环无法进行。

3.在判断上限数以及密码太小时没有把  i 的值归零,是循环重新开始。

posted on 2015-10-12 13:21  菜鸟逛街  阅读(165)  评论(0编辑  收藏  举报