约瑟夫环的c++实现

//约瑟夫环
#include<iostream>
using namespace std;
template<class T>
struct Node   //结点结构
{
	T data;   //结点数据
	Node<T> *next;
};
template<class T>
class linklist//循环链表
{
	Node<T> *current, *front;
public:
	linklist() :current(NULL), front(NULL) {}//无参构造
	linklist(T a[], int maxsize)//有参构造
	{
		int i;
		Node<T> *p;
		current = new Node<T>;
		current->data = a[maxsize - 1];
		front = current;
		for (i = maxsize - 2; i >= 0; i--)//前移
		{
			p = new Node<T>;
			p->data = a[i];
			p->next = current;
			current = p;
		}
		front->next = current;
	}
	~linklist();//析构
	bool insert(T &x);//插入
	T Delete(T &x);//删除
	void Output();//输出元素
	bool toLocatioin(T &t);//定位元素
	void move(int t);//后移
	T GetCurrentData() { return current->data; }//返回
};
template<class T>
linklist<T>::~linklist()
{
	while (current != front)
	{
		Node<T> *r = current;
		current = current->next;
		delete r;
	}
	delete current;
}
template<class T>
bool linklist<T>::insert(T &x)
{
	Node<T> *s = new Node<T>;
	s->data = x;
	if (!s)
		return false;
	if (!current)  //原循环链表为空
		current = front = s->next = s;
	else //原循环链表非空
	{
		s->next = current->next;
		current->next = s;
		front = current;
		current = s;
	}
	return true;
}
template<class T>
T linklist<T>::Delete(T &x)
{
	if (!current)//循环链表为空
		return false;
	x = current->data;
	if (current == front)//链表中只有一个元素
	{
		delete current;
		current = front = NULL;
	}
	else
	{
		front->next = current->next;//修改链表指针
		delete current;
		current = front->next;
	}
	return true;
}
template<class T>
void linklist<T>::Output()
{
	if (!current)//循环链表为空
		return;
	Node<T> *p = current;
	do
	{
		cout << p->data << "  ";
		p = p->link;
	} while (p != current);
	cout << endl;
}
template<class T>
void linklist<T>::move(int t)
{
	for (int i = 1; i <= t; i++)
	{
		front = current; // front后移
		current = current->next; //current后移
	}

}
template<class T>
bool linklist<T>::toLocatioin(T &t)//将current指向元素为t的结点,若没有则current不移动
{
	if (!current)//循环链表为空
		return false;
	Node<T> *current1 = current, *front1 = front;
	while (current1->data != t) //寻找元素t
	{
		front1 = current1;
		current1 = current1->next;
		if (current1 == current)// 已寻找一圈没有元素为t的结点
			return false;
	}
	current = current1; //current指向元素为t的结点
	front = front1;
	return true;
}
class Joseph //	约瑟夫环类
{
private:
	int numOfBoy;  //圈中人数
	int startPosition;  //报数起始点
	int interval;     //报数间隔
public:
	Joseph(int boys, int start, int m) :numOfBoy(boys), startPosition(start), interval(m) {}//构造函数
	void setNumOfBoy(int num) { numOfBoy = num; }//重置圈中人数
	void setStartPosition(int start) { startPosition = start; }//重置起始点
	void setInterval(int inter) { interval = inter; }//重置报数间隔
	int GetWinner();//求得最终优胜者编号
	void print();   //输出约瑟夫环
};
int Joseph::GetWinner()
{
	linklist<int> boys;
	for (int i = 1; i <= numOfBoy; i++)//创建循环链表,编号依次为1~numOfBoy
	{
		boys.insert(i);
	}
	boys.toLocatioin(startPosition);   //找到报数起点
	cout << endl << "依次出列的小孩是:" << endl;
	for (int i = 1; i < numOfBoy; i++)   //numOfBoy-1个小孩出圈
	{
		int x;
		boys.move(interval - 1);  //报数
		boys.Delete(x); //出圈
		cout << x << "  ";  //输出出圈编号
	}
	return boys.GetCurrentData();  //返回优胜者编号
}
void Joseph::print()   //输出约瑟夫环
{
	cout << "圈中人数:" << numOfBoy << endl;
	cout << "报数起始点:" << startPosition << endl;
	cout << "报数间隔:" << interval << endl;
}

int main()
{
	int total, interv, startboy;
	cout << "请输入初始数据:小孩数,起始小孩号码,间隔数:\n";
	cin >> total >> startboy >> interv;
	Joseph jose(total, startboy, interv);
	jose.print();
	cout << "优胜者编号为: " << jose.GetWinner() << endl;
	system("pause");
	return 0;
}

测试结果:
在这里插入图片描述

循环链表约瑟夫环是一个经典的问题,下面是一个实现: ``` class Node: def __init__(self, data): self.data = data self.next = None class CircularLinkedList: def __init__(self): self.head = None self.tail = None def append(self, data): if not self.head: self.head = Node(data) self.tail = self.head self.head.next = self.tail else: new_node = Node(data) self.tail.next = new_node self.tail = new_node self.tail.next = self.head def remove(self, node): if self.head == node: if self.head == self.tail: self.head = None self.tail = None else: self.head = self.head.next self.tail.next = self.head else: prev_node = self.head while prev_node.next != node: prev_node = prev_node.next prev_node.next = node.next if self.tail == node: self.tail = prev_node def __len__(self): count = 0 curr_node = self.head while curr_node: count += 1 curr_node = curr_node.next if curr_node == self.head: break return count def __iter__(self): curr_node = self.head while curr_node: yield curr_node curr_node = curr_node.next if curr_node == self.head: break def josephus(circle, step): curr_node = circle.head while len(circle) > 1: for i in range(step - 1): curr_node = curr_node.next next_node = curr_node.next circle.remove(curr_node) curr_node = next_node return circle.head.data if __name__ == '__main__': c = CircularLinkedList() for i in range(1, 11): c.append(i) print(josephus(c, 3)) # 输出 4 ``` 这个实现中,我们首先实现了一个循环链表的类 `CircularLinkedList`,它包含了 `append` 和 `remove` 方法,分别用于添加和删除节点。在 `__len__` 和 `__iter__` 方法中,我们实现了对链表长度和遍历的支持。 在 `josephus` 函数中,我们首先将当前节点 `curr_node` 初始化为链表头节点,然后每次循环,我们将 `curr_node` 向前移动 `step - 1` 步,找到下一个要删除的节点 `next_node`,然后通过 `circle.remove` 方法将当前节点 `curr_node` 从链表中删除。最后,我们将 `curr_node` 更新为 `next_node`,继续循环,直到链表中只剩下一个节点为止。 在主函数中,我们创建了一个含有 10 个节点的循环链表,然后调用 `josephus` 函数,传入循环链表和步长 3,输出结果为 4,符合预期。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值