双向链表 约瑟夫合并(C++)

#include<iostream>
using namespace std;
class dnode{//定义节点 
	public:
		int nodeValue;//该节点的值 
		dnode *prev;//连接前后两个节点 
		dnode *next;
		dnode(){
			next=this;
			prev=this;
		}
		dnode(const int &value):nodeValue(value){
			next=this;
			prev=this;
		}
};
class myList{
	private:
		dnode *first;
		int size;
	public:
	void push_back(int data);
	void pop_back();
	void push_front(int data);
	void pop_front();
	void insert(int pos,int data);
	void erase(int pos);
	void print();
	void printone(int pos);
	~myList(){//析构函数 
		dnode *p=first->next ;
		dnode *p1;
		while(p!=first){
			p1=p;
			p=p1->next ;
			delete p1;
		}
	}
	myList():first(),size(0){
		first=new dnode(0); 
		first->next =first;//当只有一个哑元节点时,该节点前后的节点就是节点本身
		first->prev =first;
	}
	int getsize(){
		return size;
	}
	
};
//输出特定节点的值 
void myList::printone(int pos){
	dnode *p=first ;
	int k=0;
	while(k!=pos){//从前到后找到那个节点 
		p=p->next ;
		k++;
	}
	cout<<p->nodeValue<<" "; 
}
// 在最后面加入节点 
void myList::push_back(int data){
	dnode *p=new dnode(data) ;
	dnode *p1=first->prev ;//p1即为最后一个节点 
	p1->next =p;//使p1 与p 连接起来 
	p->prev =p1;
    p->next =first;//是 p与first连接起来 
    first->prev =p;
	size++;	
}
//删除最后一个节点 
void myList::pop_back(){
	dnode *p=first->prev;//p为最后一个节点 
	p->prev->next =first;//使p的前一个节点与first连接 
	first->prev =p->prev ;
	size--;
	delete p;
}
//在最前面插入节点 
void myList::push_front(int data) {
	dnode *p=new dnode(data);
	p->prev =first;//使P的前一个节点为first 
	p->next =first->next ;//使P的后一个节点为原本的第一个 
	first->next->prev =p;//使first 与 p节点相连 
	first->next =p;
	size++;
	
}
//删除最前面的那个节点 
void myList::pop_front(){
	dnode *p=first->next ;//找到最前面的那个节点p 
	first->next=p->next ;//使first后的节点变为原本的第二个	
	p->next->prev=first;//使原本第二个节点与first 相连(即变为第一个节点) 
	size--;
	delete p;
	
}
//删除特定节点 
void myList::erase(int pos){
	
	int i=0;
	dnode *p=first;
	while(i!=pos){//找到特定的节点 
		p=p->next ;
		i++;
	}
	//使该节点的前一个节点 与 后一个节点相连 
    p->prev->next =p->next ;
    p->next->prev =p->prev ;
    size--;
    delete p;
    
   	
} 
//在pos 的位置 插入一个节点 
void myList::insert(int pos,int data) {
	
	int i=0;
	dnode *p1=new dnode(data);
	dnode *p=first;
	while(i!=pos){//找到pos位置的节点 
		p=p->next ;
		i++;
	}
	 
	p1->prev =p->prev ;//将要插入的节点 前面连接好 
	p->prev->next =p1;//将要插入的节点 后面连接好 
	p->prev =p1;
	p1->next =p;
	size++;
	
}
//输出每个节点的值 
void myList::print() {
	 dnode *p=first->next ;
	while(p->next!=first){//一个个往后输出 
		cout<<p->nodeValue <<" ";
		p=p->next ;
	}
	cout<<p->nodeValue <<endl;

}
//约瑟夫问题 找到最后出局的那个人 
void findlastone(int n,int m){
     myList l2;
     int k=0;
     while(k!=n){
     	k++;
     	l2.push_back(k);//将序号作为值加入链表中 
	 }
	 int x=1;
	 int pos=1;
	 while(l2.getsize() !=1){//当只剩一个人时不再进行 
	 	int s=l2.getsize() ;
	    pos++;//一个个报数 
	    x++;//一个个报数 
	 if(pos==s+1 )pos=1;//已经报完一轮 又要再从第一个开始 
	 if(x==m){//报到那个数了 
	 	x=0;
	 	l2.printone(pos);//将出局的序号输出 
	 	cout<<"出局"<<endl;
	 	l2.erase(pos) ;//将给节点删除 即不再参与报数 
	 	pos=pos-1;//退回前一个节点 再开始报数 
	 	
	 
	 }
}
  l2.printone(1);
  cout<<"这个人活到最后"<<endl;
}
int main(){
	/*
	//测试双向链表的各个功能 
	myList l1;
	l1.push_back(12);l1.push_back(13) ;l1.push_back(14);l1.push_back(15);
	l1.print() ;  //输出 12 13 14 15 
	l1.pop_back();l1.print() ;//输出 12 13 14 
    l1.push_front(11);l1.print() ;//输出 11 12 13 14 
    l1.pop_front();l1.print() ;//输出 12 13 14 
    l1.insert(1,11) ;l1.print() ;//输出11 12 13 14 
    l1.erase(1) ;l1.print() ;*/// 输出 12 13 14 
    
    
    int n,m;//n为总共的人数 m为报的号 
    while(cin>>n>>m)
    
    findlastone(n,m);	 
} 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值