匿名用户
1级
2009-10-11 回答
下面这个程序是我上学期学数据结构时写的作业,我们学校用的教材是严蔚敏老师的,我写的代码在VC++6.0上编译连接生成可执行程序:
///
#include
#include
typedef struct lnode
{
int nNumber; // 编号
int nPassword; // 密码
struct lnode *pNext;
} LNODE, *PLINKLIST;
int *Joseph( int *pPassword, int nSize, int m, int *&pNumber )
{
// *************************************************************************
// 参数:
// pPassword [in] 存储密码的一维数组首地址
// nSize [in] 数组 pPassword 中元素的个数,等于人数
// m [in] 报数上限值
// pNumber [out] 存储出列顺序的一维数组首地址,若传入的参数为 NULL ,
// 本函数将为其分配存储空间,调用者负责释放本函数分配的存储空间
// 返回值:
// 若人数大于 0 , 函数返回存储出列顺序的一维数组首地址 pNumber
// 若人数小于等于 0 , 函数返回 NULL
// *************************************************************************
if ( nSize <= 0 )
{ // 若人数小于等于 0 , 返回 NULL
return NULL;
}
// 处理第一个结点,第一个结点的指针域指向其自身
PLINKLIST pFirst = ( PLINKLIST ) malloc( sizeof ( LNODE ) );
pFirst->pNext = pFirst;
pFirst->nNumber = 1;
pFirst->nPassword = pPassword[0];
// 创建循环链表时, pRear 指向上次刚创建的结点
PLINKLIST pRear = pFirst;
// 采用尾插法创建循环链表
for ( int i = 1; i < nSize; i++ )
{
PLINKLIST p = ( PLINKLIST ) malloc( sizeof ( LNODE ) );
p->nNumber = i + 1;
p->nPassword = pPassword[i];
p->pNext = pRear->pNext;
pRear->pNext = p;
pRear = pRear->pNext;
}
// 若引用的指针变量 pNumber 为 NULL,由本函数为其分配存储空间
if ( NULL == pNumber)
{
pNumber = ( int * ) malloc( nSize * sizeof ( int ) );
}
// 数组 pNumber 的下标
int nSuffix = 0;
// 存储当前报数值
int nCount = 0;
// 循环报数,指针 p 指向当前报数结点的前一个结点,当只剩 1 人时终止循环
PLINKLIST p = pRear;
while ( p->pNext != p )
{
// 当前报数值自增 1
nCount++;
if ( nCount == m )
{ // 若当前报数值等于报数上限值
// 将当前报数值清 0
nCount = 0;
// 更改报数上限值为报数结点的密码( p 指向当前报数结点的前一个结点)
m = p->pNext->nPassword;
// 记录报数结点的编号
pNumber[nSuffix++] = p->pNext->nNumber;
// 删除报数的结点,删除后 p 指向即将报数结点的前一个结点
PLINKLIST t = p->pNext;
p->pNext = t->pNext;
free( t );
t = NULL;
}
else
{ // 若当前报数值不等于报数上限值
// p 指向下一个结点,继续循环报数
p = p->pNext;
}
}
// 此时,只剩 1 人,将其编号存入数组,释放对应结点的存储空间
pNumber[nSuffix] = p->nNumber;
free( p );
p = NULL;
// 返回存储出列顺序的一维数组首地址 pNumber
return pNumber;
}
int main()
{
int n = 0;
printf( "请输入人数:" );
scanf( "%d", &n );
int m = 0;
putchar( '\n' );
printf( "请输入报数上限值:" );
scanf( "%d", &m );
putchar( '\n' );
printf( "请依次输入每个人的密码\n" );
int *psw = ( int * ) malloc( n * sizeof ( int ) );
for ( int i = 0; i < n; i++ )
{
printf( "第 %d 个人的密码:", i + 1 );
scanf( "%d", &psw[i] );
}
int *pNumber = NULL;
printf( "\n出列顺序为:" );
for ( int *p = Joseph( psw, n, m, pNumber ); p < pNumber + n; p++ )
{
printf( "%d ", *p );
}
putchar( '\n' );
free( psw );
psw = NULL;
free( pNumber );
pNumber = NULL;
return 0;
}