回 帖 发 新 帖 刷新版面

主题:[原创]约瑟夫环-我的第一个数据结构实验(好激动啊~)

#include <iostream>
using namespace std;

typedef struct LNode
{
    int num,pwd;
    struct LNode *next;
}LNode,*LinkList;

int main()
{    
    int i,j,m,n;                            //m为报数上限,n为人数。
    cout<<"Please enter n=";
    if(!(cin>>n)) {cout<<"ERROR:That's not a number!";return -1;}
    cout<<"Please enter m=";
    if(!(cin>>m)) {cout<<"ERROR:That's not a number!";return -2;}
    LinkList head,tail,p,q;                 //head为头结点指针,tail为尾结点
                      //指针,p为当前指针的前一指针,q
                                            //当前指针。
    head=new LNode;
    p=head;
    for(i=1;i<n;i++)
    {
        q=new LNode;
        p->next=q;
        p=q;
    }
    tail=q;
    tail->next=head;                        //建立n个结点的循环链表。

    p=head;
    for(i=1;i<=n;i++)
    {
        p->num=i;
        cout<<"Please enter No."<<i<<"'s password:";
        cin>>p->pwd;
        p=p->next;
    }                                       //输入密码。

    cout<<"result:";
    p=tail;
    for(i=1;i<=n;i++)
    {
        for(j=1;j<m;j++) p=p->next;
        q=p->next;
        m=q->pwd;
        cout<<" "<<q->num;
        p->next=q->next;
        delete q;
    }                                       //输出编号。
    return 0;
}

回复列表 (共20个回复)

11 楼

楼主,你的程序在机子上不能运行


--------------------Configuration: k1 - Win32 Debug--------------------
Compiling...
1.cpp
d:\c++\msdev98\myprojects\c学习\k1\1.cpp(49) : fatal error C1010: unexpected end of file while looking for precompiled header directive
执行 cl.exe 时出错.子上好像不能运行,我一运行它就出现:

12 楼

你这个约瑟夫是不是最原始的那个??
下面是我的(最原始的约瑟夫):
#define MAX 50
main()
{
    int a[MAX];
    int i,m,k,n;
    scanf("%d",&n);
    for(i=0;i<n;i++)
        a[i]=i+1;
    i=0;
    m=0;
    k=0;
    while(m<n-1)
    {
        if(a[i]!=0)
            k++;
        if(k==3)
        {
            a[i]=0;
            k=0;
            m++;
        }
        i++;
        if(i==n)
            i=0;
    }
    i=0;
    while(a[i]==0)
        i++;
    printf("%d",a[i]);
}

13 楼

约瑟夫环链:N个人围成一个环,设置起点start,从起点开始从1报数,报到div(除数)的元素退出环链,该元素的下一个元素重新从1开始报数,知道环链剩下一个元素为止


#include "iostream.h"
#include "process.h"
#include "conio.h"
#include "iomanip.h"
#define N 20
typedef struct Node
{
    int number;//元素号码,即编号
    int value;//元素的值,即所报的数
    Node *next;
}Node,*NodePos;
typedef struct
{
    NodePos head;
    int length;
}Joseph;
void InitJoseph(Joseph &l)
{
    NodePos p;
    p = l.head = new Node;
    l.head->number = 1;
    for(int i = 2;i <= N;i++)
    {
        p->next = new Node;
        p = p->next;
        p->number = i;
    }
    p->next = l.head;
    l.length = N;
}
void PrintJosephNumber(Joseph &l)
{
    NodePos p = l.head;
    do
    {
        cout<<p->number<<setw(5);
        p = p->next;
    }
    while(p != l.head);
    cout<<endl;
}
void DelNode(Joseph &l,int start,int div)
{
    int n = 1;
    NodePos p = l.head;
    NodePos q;
    while(p->number != start)//evaluate the start point of one
        p = p->next;
    p->value = n++;
    while(l.length != 1)
    {
        q = p;
        p = p->next;
        p->value = n++;
        if(p->value % div ==0)
        {
            n = 1;
            cout<<setw(5)<<p->number;//输出退出元素的号码
            q->next = p->next;
            l.length--;
        }
    }
    cout<<endl<<q->number<<endl;//through debugging, 'q' is right,not 'p'
}
void main()
{
    Joseph   l;
    int  start,div;
    InitJoseph(l);
    PrintJosephNumber(l);
    cout<<"Input the start and the divisor:";//输入报数起点和除数
    cin>>start>>div;
    DelNode(l,start,div);
    getch();
}

14 楼

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

int main(int argc, char *argv[])
{
    int m, n, step=0, index=0, cir=0, t;
    scanf("%d%d", &m, &n);
    char *out = (char*)malloc(m);
    if(!out)  return -1;
    memset(out, 0, m);
    while(1)
    {
        if(step==m)  break;
        while(cir<n)
        {
            if(!out[index]) ++cir;
            index=(index+1)%m;          
        }     
        cir=0; ++step; out[(index+m-1)%m]=1;
        printf("\nNo.%d out.", !index?m:index);
    }    
    free(out);
    system("PAUSE");    
    return 0;
}



我也写了一个

15 楼


输入判断做好了 呵呵!

16 楼

#include <stdio.h>
#include <stdlib.h>

typedef struct node{
     int  code;   /*游戏者的编号*/ 
     unsigned int  cipher;  
     struct node *next;
}Node,*LinkList;
LinkList  create_list(int n)
{  LinkList head, p,r;   int i;
    head = (Node *)malloc(sizeof(Node)); /*创建循环链表的第一个结点*/
    if (!head) 
        { printf("memory allocation error!\n"); return NULL;}
    printf("input cipher:");    scanf("%d",&(head->cipher)); 
    head->code = 1;     head->next = head;    r = head;
    for(i = 2; i <= n; i++)  /*尾插法创建循环链表的其余n-1个结点*/
    {   p = (Node *)malloc(sizeof(Node));
         if (!p)
           {printf("memory allocation error!\n");  exit(1);}
         printf("input cipher:");   scanf("%d",&(p->cipher)); 
         p->code = i;   p->next = r->next;    r -> next = p;    r = p;
    }/*for*/
    return r;  
}/* create_list */

void output(LinkList head) 
{  LinkList p;
    p = head;
    do {
        printf("%4d",p->code);p = p->next;
    }while (p != head);
    printf("\n");
}/*output*/
void play(LinkList tail,int n,int m) 
{  LinkList prep, p;
    int c = 0, k, found = m % n ? m % n : n;
    prep = tail;  p = tail -> next;  c = 1;  k = n; 
    while (k > 1) {
       if (c == found)   /*p指向的结点为需要删除的结点*/
           {  printf("%4d", p->code); 
              prep -> next = p -> next;      k--;
              found = p -> cipher % k ? p -> cipher % k : k;
               free(p);     
               p = prep -> next;
              c = 1;
           }
       else 
          {c++; prep = p ; p = p->next;}
    }/*while*/
    printf("\n%4d was the winner.",p->code);
}/*play*/
void main(void) 
{  LinkList tail;
   int n;
   printf("input the number of players:"); scanf("%d",&n);
   tail = create_list(n);   /*创建单循环链表*/
   if (tail)
   { output(tail->next);  /*输出单循环链表中结点的信息*/
     play(tail,n,20);
   }
}

17 楼

#include <stdio.h>
#include <stdlib.h>

int main( void )
{
    int n, i=0, m, p;
    scanf("%d%d", &n, &m);
    while (++i <= n ){
        p=i*m;
        while( p>n )
            p = p - n + (p-n-1)/(m-1);
           printf("%d\n", p);
    }    
    system("PAUSE");    
}


忍不住再贴一个

18 楼


#include<iostream.h>
#include<conio.h>    //getch();
/*write: Han.JH*/
static int    people_number_count;                                         
typedef struct People_Node      
{
    int Password_Data,people_number;
    struct People_Node *next;
}People_Node,*People_LinkList;

void GreatList(People_LinkList &L)   
{
    People_Node *s,*r; int flag=1;int Password;
    L=new People_Node;
    L->next=NULL;
    r=L;
    while(flag==1)
    {
        cout<<"输入每个人的密码,以回车作间隔,'0'表示结束:";
        cin>>Password;//输入每个人的密码;
        if(Password!=0)
        {
            s=new People_Node;
            s->Password_Data=Password;
            people_number_count++;     //对人的编号
            s->people_number=people_number_count;
            r->next=s;
            r=s;
        }
        else
        {  r->next=L->next;      
           flag=0;
        }
    
    }

}        
void GetList(People_LinkList &L)
{   
    People_Node *r;
    int m,k;int count=0; 
    cout<<"输入报数上限值m:";
    cin>>m;
    r=L;
         cout<<"出列排序:";
    while(count!=people_number_count)
    {                                 //则所有人以出列,结束循环
        for(k=1;k<=m-1;k++)
        {
          r=r->next;
        }
     count++;
     m=r->next->Password_Data;
     cout<<"["<<r->next->people_number<<"]";
     r->next=r->next->next;
    }
}
void main()
{       
    People_LinkList L;
    void GreatList(People_LinkList &);
    void GetList(People_LinkList &);
    cout<<"++++++++++++约瑟夫环问题+++++++++++"<<endl;
    GreatList(L);
           GetList(L);
    cout<<"[--结束--]"<<endl;
    getch();
}
看看我编的。

19 楼

嗯,很好,干得不错.

记住,要写的更有条理.

把需要用到的数据结构以及与这个数据结构相应的操作函数,都单独写出来,放到另外一

个文件里面,通过include编译指令包含进来

其次,把约瑟夫这个单独放到一个函数里面实现..


不要都丢到main里面.


说细点,这程序应该怎么写呢?

这个好像是第二章里面的,是属于链表/队列,也就是说约瑟夫环需要用到链表/队列.

那链表来举例.

首先你就要实现链表的存储结构.

再次,你要实现链表上面的 插入 和 删除 操作.

好这样就开始写约瑟夫环了.

先写个while(Link.length),也就是链表非空,就一直循环.

其次,while里面就开始写实现细节.

被点到的人,就用 delete(&Link,position)删除.

这样大量的实现细节被隐藏了之后,程序就非常容易懂了.

总结一句,就是要把实现的细节和函数的逻辑尽量的进行剥离,这才叫做编程的艺术.


这样做的好处,就是你不用反复实现 链表这样的数据结构,方便你今后的数据结构编码实验中重用.

20 楼

可以用数学方法去解的呀!
这样既省空间又省时间,一举多得!
可以找规律,有一个递推关系!
F[1] = 1;
F[N] = [(F[N-1]+M)%N);
================================

我来回复

您尚未登录,请登录后再回复。点此登录或注册