双向循环链表-解决顺逆时针约瑟夫环

题目来自苏州OJ 数据结构第二题;

内容:

【问题描述】
有n个人围坐在一个圆桌周围,把这n个人依次编号为1~n。从编号为1的人开始顺时针报数,报到m1的人出列;然后逆时针方向报数,报到m2的人出列。问最后谁出列?(从1开始顺时针数M1,第M1个人出局,然后逆时针数M2,第M2个人出局,以此类推)
【输入】
输入数据仅一行,包含三个用空格隔开的正整数n,m1和m2。
【输出】
数据数据仅一行,包含一个正整数k,即最后一个人的序号。
【样例】
输入
10 5 7
输出
6

我录入了书本上的双向循环链表的全部代码,便于以后深入研究。(并且添加了几个函数,便于解这道题)
DblList.h
#include<stdlib.h> 
using namespace std;
template<class T>
struct DblNode{
	T data;
	DblNode<T> *lLink, *rLink;
	DblNode(DblNode<T> *left = NULL, DblNode<T> *right = NULL) :lLink(left), rLink(right){}
	DblNode(T value, DblNode<T> *left = NULL, DblNode<T> *right = NULL) :data(value), lLink(left), rLink(right){}
};
template<class T>
class DblList {
public:
	DblList();
	DblList(T uniqueVal);
	~DblList(){ ; }
	int Length() const;
	bool IsEmpty(){ return first->rLink == first; }
	DblNode<T> *Search(const T&x);
	DblNode<T>*Locate(int i, int d);
	bool Insert(int i, const T&x, int d);
	bool Remove(int i, T&x, int d);
	DblNode<T> OutPut(DblList &L);
	void Jos(int n, int p, int q, int d);
	//private:
	DblNode<T> *first, *nail;
};
template<class T>
DblList<T>::DblList(T uniqueVal){
	first = new DblNode<T>(uniqueVal);
	if (first == NULL) { cerr << "存储分配错误" << endl; exit(1); }
	first->rLink = first->lLink = first;
}
template<class T>
int DblList<T>::Length()const {
	DblNode<T> *current = first->rLink; int count = 0;
	while (current != first){ current = current->rLink; count++; }
	return count;
}
template<class T>
DblNode<T> *DblList<T>::Search(const T&x){
	DblNode<T> *current = first->rLink;
	while (current != first || current->data != x)
		current = current->rLink;//没回到起点,也没搜索到值
	if (current != first)return current;//搜索成功
	else return NULL; //失败
}
template<class T>
DblNode<T> *DblList<T>::Locate(int i, int d){ //Direction 0是左
	if (first->rLink == first || i == 0) return first;
	DblNode<T> *current;
	if (d == 0)  current = first->lLink;
	else current = first->rLink;

	for (int j = 1; j < i; j++){
		if (current == first) break;
		else if (d == 0)current = current->lLink;
		else current = current->rLink;
	}
	if (current != first) return current;
	else return NULL;
}

template<class T>
bool DblList<T>::Insert(int i, const T&x, int d){  //Direction 0是左
	DblNode<T> *current = Locate(i, d);
	if (current == NULL) return false;
	DblNode<T> *newNode = new  DblNode<T>(x);
	if (newNode == NULL){ cerr << "存储分配错误!" << endl; }
	if (d == 0){
		newNode->lLink = current->rLink;
		current->lLink = newNode;
		newNode->lLink->rLink = newNode;
		newNode->rLink = current;
	}
	else
	{
		newNode->rLink = current->rLink;
		current->rLink = newNode;
		newNode->rLink->lLink = newNode;
		newNode->lLink = current;
	}
	return true;
}
template<class T>
bool DblList<T>::Remove(int i, T &x, int d){
	DblNode<T>*current = Locate(i, d);
	if (current == NULL) return false;
	current->rLink->lLink = current->lLink;
	current->lLink->rLink = current->rLink;
	x = current->data;
	if (d == 0) nail = current->lLink;
	else nail = current->rLink;

	delete current;
	return true;
}
template<class T>
DblNode<T> DblList<T>::OutPut(DblList &L){
	DblNode<T>*current = first; int cnt = 0;
	while (cnt <= L.Length()){
		cout << " No:" << ++cnt << " is:" << current->data << endl;
		current = current->rLink;
	}
	return current;

}
template<class T>
void DblList<T>::Jos(int n, int x, int y, int d){

	DblNode<T> *p = first;
	if (d % 2 == 0){
		while (x > 0)
		{
			p = p->rLink;
			--x;
		}
		p->lLink->rLink = p->rLink;//确定位置后,删除结点P
		p->rLink->lLink = p->lLink;
	}

	else if (d % 2 != 0){
		while (y > 0)
		{
			p = p->lLink;
			--y;
		}
		p->lLink->rLink = p->rLink;//确定位置后,删除结点P
		p->rLink->lLink = p->lLink;
	}
	
	if (d % 2 == 0) first = p->lLink;//先顺时针,后逆时针
	else first = p->rLink;
	delete p;
	d++;
}
main.cpp
#include<iostream>
#include"DblList.h"
int main()
{
	DblList<int> List(1);
	for (int i = 0; i <9; i++)
		List.Insert(i, i + 2, 1);
	int x = -100; int y = -100;

	for (int i = 0; i < 4; i++){
		List.Jos(10, 4, 6, 0);
		List.Jos(10, 4, 6, 1);
	}
	List.Jos(10, 4, 6, 0);
	List.OutPut(List);
	
	system("pause");
	return 0;
}
最后输出 6;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值