用循环单链表作为存储结构完成约瑟夫问题的完整代码
时间: 2023-06-17 09:05:47 浏览: 88
下面是用循环单链表实现约瑟夫问题的完整代码,注释中会有详细的说明:
```python
class Node:
def __init__(self, data=None):
self.data = data
self.next = None
class CircularLinkedList:
def __init__(self):
self.head = None
def add_node(self, data):
new_node = Node(data)
if not self.head:
self.head = new_node
new_node.next = self.head
else:
curr = self.head
while curr.next != self.head:
curr = curr.next
curr.next = new_node
new_node.next = self.head
def remove_node(self, node):
if not self.head:
return
elif self.head == node:
curr = self.head
while curr.next != self.head:
curr = curr.next
curr.next = self.head.next
self.head = self.head.next
else:
curr = self.head
prev = None
while curr.next != self.head:
prev = curr
curr = curr.next
if curr == node:
prev.next = curr.next
curr = curr.next
def get_node(self, index):
if not self.head:
return None
curr = self.head
i = 0
while i < index:
curr = curr.next
i += 1
return curr
def get_size(self):
if not self.head:
return 0
curr = self.head
size = 0
while curr.next != self.head:
size += 1
curr = curr.next
return size + 1
def josephus(n, k):
cll = CircularLinkedList()
# 添加n个节点
for i in range(1, n+1):
cll.add_node(i)
curr = cll.get_node(0)
while cll.get_size() > 1:
# 找到要删除的节点
for i in range(k-1):
curr = curr.next
# 删除节点
cll.remove_node(curr)
# 更新curr节点
curr = curr.next
return cll.head.data
n = 7
k = 3
winner = josephus(n, k)
print("Winner is:", winner)
```
其中,`Node`类表示链表中的节点,`CircularLinkedList`类表示循环单链表,`add_node()`方法用于向链表中添加节点,`remove_node()`方法用于删除节点,`get_node()`方法用于获取某个位置的节点,`get_size()`方法用于获取链表的长度。
`josephus()`函数中,首先创建一个循环单链表,然后不断找到要删除的节点,删除它,最后返回剩下的最后一个节点的值,即为胜利者的编号。
阅读全文