版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Daisymanman/article/details/52971070
实验一 线性表的应用
实验目的和要求:
通过实验进一步理解线性表的逻辑结构和存储结构,提高使用理论知识指导解决实际问题的能力,熟练掌握链表的实际应用。
主要内容:
题目1 :Josephus环问题
问题描述:
约瑟夫(Joseph)问题的一种描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。试设计一个程序求出出列顺序。
基本要求:
利用单向循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。
测试数据:
m的初值为20;n=7,7个人的密码依次为:3,1,7,2,4,8,4,首先m值为6(正确的出列顺序应为6,1,4,7,2,3,5)。
1.建链表按书上写,不带头节点的循环链表
2.遍历 删除找前驱,更新M 值,data域
M=20,或6,序号,data域多一项
// 约瑟夫环问题.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include<iostream>
using namespace std;
typedef struct Node{
int number,password;
struct Node *next;
}LNode,*LinkList;
LinkList Creat_LinkList1(int n){ //建从尾部插入链表
LinkList L;
LNode *s, *r;
int num, m;//num为序号, m为密码
L = r = NULL;
num = 1;
while (num < n+1){
s = new LNode;
cout << "请输入第"<<num<<"个人的m值:"<<"\t" ;
cin >> m;
int p;
p=num++;
s->number =p;//序号
s->password = m; //m密码值
if (L == NULL)
L = s;//对第一个节点的处理
else
r->next = s;
r = s;//对其他节点的处理
}
if (r != NULL)
r->next = L; //最后一个元素指向头结点
return L;
}
void Joseph(LinkList L, int m)
{
LNode *p, *s, *r;
p = L;
int n1 = 1, num;
cout<<"正确的出列顺序为:"<<endl;
while (p->next!= p){
for (int i=1; i<m-1; i++)
p=p->next;//找前驱
s=p->next;
p->next = s->next;
m=s->password;//保存m值
cout<<s->number<<'\t';
delete s;//删除节点
n1++;
if (m!=1)//当m等于1时,则下一个出列的人为报1的人,则p不变,当m不等于1时,则需将p指向p->next
p = p->next;
}
cout <<p->number<<endl;;
}
int _tmain(int argc, _TCHAR* argv[]){
int m,n;
Node *L;
L=NULL;
cout << "请输入m的初始值:";
cin >>m;
LinkList L1;
cout<<"请输入总人数n:";
cin>>n;
L1 = Creat_LinkList1(n);
Joseph(L1,m);
return 0;
}