//约瑟夫环问题,不能让头结点第一个出局
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
using namespace std;
#define Status int
#define ElemType int
//单链表结点数据结构
typedef struct LNode
{
ElemType data;//数据域
struct LNode *next;//指针域
LNode():data(0),next(nullptr) {}
LNode(int x):data(x),next(nullptr) {}
}LNode,*LinkList;
//初始化函数
Status InitList(LinkList &L)
{
L = new LNode;//生成头结点 这样删除等操作就不必分第一个结点和其他了
L->next = nullptr;
return 1;
}
//快速创建一个链表
Status CreatList(LinkList &L)
{
int n;
cout<<"请输入创建链表的长度:";
cin>>n;
cout<<"请输入链表节点的值:";
LNode *p = new LNode;
int num;
cin>>num;
p->data = num;
L->next = p;
for(int i=0; i<n-1; i++)
{
int num;
cin>>num;
LNode *node = new LNode(num);
p->next = node;
p = p->next;
}
p->next = nullptr;
return 1;
}
//遍历输出函数
void PrintList(LinkList L)
{
LNode *p = L;
cout<<"链表的元素为:";
if(L!= nullptr)
{
p = p->next;
while(p){
cout<<p->data<<" ";
p = p->next;
}
cout<<endl;
}
else
{
cout<<"链表为空"<<endl;
}
}
//使得单链表成为一个循环链表
void CirList(LinkList &head)
{
head = head->next; //跳过头结点,直接获取首元结点
LNode* temp = head;
//链表为空或者长度为1直接返回头结点
if(!head||!head->next) {
cout<<"链表为空或者只有一个元素"<<endl;
return ;
}
//使得链表成为循环链表
while(head)
{
if(head->next== nullptr){
head->next = temp;
break;
}
head = head->next;
}
head = temp;
}
LNode* DeleteList(LinkList &L, int i)
{
LinkList p=L;
LinkList q;
if(i>2)
{
for(int m=0; m<i-2; m++)
{
p = p->next;
}
}
q = p->next;
p->next = q->next;
q->next = nullptr;
L = p->next;
return q;
}
int main()
{
LinkList L;int choice;
InitList(L);
CreatList(L);
CirList(L);
LinkList temp = new LNode(0);
LinkList dummy = temp;
int order = 0;
cout<<"约瑟夫参数为:";
cin>>order;
while(L->next != L)
{
temp->next = DeleteList(L,order);
temp = temp->next;
}
cout<<"成功!!!"<<endl;
temp->next = L;
temp = temp->next;
temp->next = nullptr;
cout<<"约瑟夫";
PrintList(dummy);
return 0;
}
该问题是关于约瑟夫环问题,使用循环链表实现。第一次使用csdn发布文章,之后再做详细的解释。
控制台的输出: