使用链表解决约瑟夫问题

1.建立一个链表

2.定义一个指针指向最后一个节点

3.对链表进行遍历

4. 找到复合条件的节点删除掉

5. 直到剩下最后一个节点

  1. package main
  2. import "fmt"
  3. type Boy struct {
  4. No int
  5. Next *Boy
  6. }
  7. func AddBoy(num int) *Boy {
  8. first := &Boy{}
  9. if num < 1 {
  10. fmt.Printf("num 太小")
  11. return first
  12. }
  13. current := &Boy{}
  14. for i := 1; i <= num; i++ {
  15. boy := &Boy{
  16. No: i,
  17. }
  18. if i == 1 {
  19. first = boy
  20. current = boy
  21. current.Next = first
  22. } else {
  23. current.Next = boy
  24. current = boy
  25. current.Next = first
  26. }
  27. }
  28. return first
  29. }
  30. func Show(first *Boy) {
  31. if first.Next == nil {
  32. fmt.Printf("链表为空")
  33. return
  34. }
  35. current := first
  36. for {
  37. fmt.Printf("body no = %d \n", current.No)
  38. if current.Next == first {
  39. fmt.Printf("完成遍历")
  40. break
  41. }
  42. current = current.Next
  43. }
  44. }
  45. func Play(first *Boy, startNo int, count int) {
  46. if first.Next == nil {
  47. fmt.Printf("空链表")
  48. return
  49. }
  50. if startNo < 1 || startNo > 10 {
  51. fmt.Printf("编号范围错误")
  52. return
  53. }
  54. // list 最后一个节点.
  55. tail := first
  56. for {
  57. if tail.Next == first {
  58. break
  59. }
  60. tail = tail.Next
  61. }
  62. // tail 指向到 起始节点
  63. for i := 1; i <= startNo -1; i++ {
  64. first = first.Next
  65. tail = tail.Next
  66. }
  67. // 开始进行 出列
  68. for {
  69. for i := 1; i <= count; i++ {
  70. first = first.Next
  71. tail = tail.Next
  72. }
  73. fmt.Printf("boy no = %v 出列 \n", first.No)
  74. // 删除节点
  75. first = first.Next
  76. tail.Next = first
  77. // 最后一个小孩退出循环
  78. if tail == first {
  79. break
  80. }
  81. }
  82. fmt.Printf("最后一个 boy no = %v \n", tail.No)
  83. }
  84. func main() {
  85. first := AddBoy(10)
  86. Show(first)
  87. Play(first, 1, 3)
  88. }

递归解决约瑟夫问题

  1. func f(n int, m int) (int) {
  2. if n == 1 {
  3. return n
  4. }
  5. return (f(n - 1, m) + m - 1) % n + 1
  6. }