约瑟夫环问题
数据结构题目:
输入正整数n、m(m<n),设有n个人坐成一圈,从第1个人开始循环报数,报到m的人出列,然后再从下一个人开始报数,报到m的人又出列,如此重复,直到所有的人都出列为止。要求用顺序结构实现,按出列的先后顺序输出每个人的信息。
c++代码如下:
#include <iostream>
#include <stdlib.h>
using namespace std;
#define ListInitSize 256 //初次分配空间大小
#define ListIncrement 128 //空间分配增量大小
typedef struct List
{
char *pData; //动态存储空间的基地址
int length; //存储数据元素的个数
int size; //当前已分配的存储空间的大小
}List;
void InitList( List &L )
{ //初始化顺序表
L.pData = (char *)malloc(ListInitSize * sizeof(char)); //申请存储空间
if( L.pData == NULL )
exit(1); //存储空间申请失败
L.size = ListInitSize; //当前已分配的存储空间大小
L.length = 0; //存储数据元素个数为零
} //InitList
void ListTraverse( List L )
{ //访问并输出每个元素
for( int i = 0; i < L.length; i++ ) //遍历整个顺序表
{
cout<<L.pData[i]<<endl; //访问并输出元素
}
} //ListTraverse
void InsertElem( List &L, int i, char e )
{ //在顺序表第i个位置上插入数据元素e
if( i < 1 || i > L.length+1 ) //参数检查
cout<<"error2"<<endl;
if( L.length >= L.size ) //当前存储空间已满,需增加存储空间
{
char *newbase = ( char* ) realloc( L.pData, (L.size+ListIncrement)*sizeof(char) );
if( newbase == NULL )
cout<<"error3"<<endl; //内存申请失败
L.pData = newbase;
L.size += ListIncrement;
}
//从最后一个元素开始,直到下标为i-1(物理位置)的元素,依次向后挪一个位置
for( int j = L.length-1; j >= i-1; j-- )
L.pData[j+1] = L.pData[j];
L.pData[i-1] = e; //在数组下标为i-1的位置上插入元素e
L.length += 1; //顺序表的长度加1
} //InsertElem
void RingList( List &L, int m )
{
int i, j, k;
for( i = L.length; i > 0; i -- )
{
k = 0;
for( j = 0; j < i; j ++ )
{
if( L.pData[j] != '0' ) //开始报数
{
k += 1;
}
if( k == m && L.pData[j] != '0') //报到m的人出列
{
cout<<L.pData[j]<<endl; //输出要出列的人的信息
L.pData[j] = '0';
k = 0;
}
}
}
for( i = 0; i < L.length; i ++ ) //若还剩下最后一个人,直接出列
{
if( L.pData[i] != '0' )
cout<<L.pData[i]<<endl;
}
}
int main()
{
List L;
int i, n, m;
char str;
char &e = str;
cout<<"-进行初始化操作-"<<endl;
InitList(L); //初始化
cout<<"请输入人数n和数字m(m<n):"<<endl;
cin>>n>>m;
cout<<"请依次输入各人信息:"<<endl;
for( i = 1; i <= n; i ++ )
{
cin>>str;
InsertElem(L, i, e);
}
cout<<"输出顺序表如下:"<<endl;
ListTraverse(L);
cout<<endl;
cout<<"-进行约瑟夫环操作-"<<endl;
RingList(L, m);
}