数据结构C++版 王红梅 OJ习题

本文介绍了一种使用单向循环链表解决约瑟夫问题的方法,通过具体的C++代码实现展示了如何创建链表并求解约瑟夫问题中人们的出圈顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1011: 约瑟夫(Joseff)问题求解(2)

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 411  Solved: 203
[Submit][Status][Web Board]

Description

约瑟夫(Joseff)问题求解。n个人围成一圈,编号依次为1,2,。。。。n,从第一个人开始报数,m号出圈,再从下一个开始报数,。。。,m号出圈,直至所有人出圈。求出圈的次序。

要求采用仅设尾指针的单向循环链表实现。已知类的定义、部分成员函数及主函数代码如下(勿改动)。

//结点结构
template <class T>
struct Node
{
  T data;
  Node<T> *next; 
};
//单向循环链表类
template <class T>
class LinkList
{
  public:
    LinkList( );  //建立没有头结点的空链表
    ~LinkList();  //析构函数
 void RInsert(T x);   //在链表表尾插入元素x
 void Create(int n);  //利用RInsert创建仅有尾指针的单向循环链表(不设置头结点)
 void Joseff(int m);   // 约瑟夫问题求解
    void DispList( );     //遍历单链表,按序号依次输出各元素
 private:
   Node<T> *rear;  //尾指针
};

//创建空的循环表
template <class T>
LinkList<T>:: LinkList( ){
 rear=NULL;
}


//析构函数:释放链表结点所占内存单元
template <class T> 
LinkList<T>:: ~LinkList( ){  
    Node<T> *s;
 if(rear) //链表非空析构
 {
  s=rear->next;
  while (s!=rear){
   rear->next=s->next;
   delete s;
   s=rear->next;
  }
  delete s;
 }
}
//创建n个数据的链表
template <class T> 
void LinkList<T>::Create(int n){  
    int i;
 for(i=1;i<=n;i++)
  RInsert(i);
}
/*
*前置条件:单链表存在
*输    入:无
*功    能:单链表遍历
*输    出:输出所有元素
*后置条件:单链表不变
*/
template <class T>
void LinkList<T>::DispList( )
{
 Node<T> *p;
  if(rear)  //链表非空输出数据
 {
  for(p=rear->next;p!=rear;p=p->next)
   cout<<p->data<<" ";
  cout<<p->data<<" ";
 }
 cout<<endl;
}
int main( ){
 LinkList<int> sa;
 int m,n;
 cin>>n>>m;
 sa.Create(n);  //创建n个人(编号1~n)的链表
    sa.DispList(); // 遍历链表,输出编号
 sa.Joseff(m);  // 输出出圈人的编号次序
 return 0;
}

Input

输入次序为n,m

Output

Sample Input

10 5

Sample Output

1 2 3 4 5 6 7 8 9 10 
5 10 6 2 9 8 1 4 7 3 
#include <iostream>

using namespace std;

//结点结构
template<class T>
struct Node {
    T data;
    Node<T> *next;
};

//单向循环链表类
template<class T>
class LinkList {
public:
    LinkList();  //建立没有头结点的空链表
    ~LinkList();  //析构函数
    void RInsert(T x);   //在链表表尾插入元素x
    void Create(int n);  //利用RInsert创建仅有尾指针的单向循环链表(不设置头结点)
    void Joseff(int m);   // 约瑟夫问题求解
    void DispList();     //遍历单链表,按序号依次输出各元素
private:
    Node<T> *rear;  //尾指针
};

//创建空的循环表
template<class T>
LinkList<T>::LinkList() {
    rear = NULL;
}

//析构函数:释放链表结点所占内存单元
template<class T>
LinkList<T>::~LinkList() {
    Node<T> *s;
    if (rear) //链表非空析构
    {
        s = rear->next;
        while (s != rear) {
            rear->next = s->next;
            delete s;
            s = rear->next;
        }
        delete s;
    }
}

//创建n个数据的链表
template<class T>
void LinkList<T>::Create(int n) {
    int i;
    for (i = 1; i <= n; i++)
        RInsert(i);
}

template<class T>
void LinkList<T>::DispList() {
    Node<T> *p;
    if (rear)  //链表非空输出数据
    {
        for (p = rear->next; p != rear; p = p->next)
            cout << p->data << " ";
        cout << p->data << " ";
    }
    cout << endl;
}

template<class T>
void LinkList<T>::RInsert(T x) {
    Node<T> *s = new Node<T>;
    s->data = x;
    if (rear == NULL) {
        rear = s;
        rear->next = s;
    } else {
        s->next = rear->next;
        rear->next = s;
        rear = s;
    }
}

template<class T>
void LinkList<T>::Joseff(int m) {
    if (rear) {
        int cnt = 0;
        while (rear != rear->next) {
            Node<T> *q = rear->next;
            cnt++;
            if (cnt == m) {
                rear->next = q->next;
                cout << q->data << " ";
                cnt = 0;
                delete q;
            } else
                rear = rear->next;
        }
        cout << rear->data;
        delete rear;
        rear = NULL;
    }
}

int main() {
    LinkList<int> sa;
    int m, n;
    cin >> n >> m;
    sa.Create(n);  //创建n个人(编号1~n)的链表
    sa.DispList(); // 遍历链表,输出编号
    sa.Joseff(m);  // 输出出圈人的编号次序
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值