先来看递归函数的方式:
/*
* .::::.
* .::::::::.
* :::::::::::
* ..:::::::::::'
* '::::::::::::'
* .::::::::::
* '::::::::::::::..
* ..::::::::::::. Utils:递归函数求解汉诺塔游戏
* ``:::::::::::::::: Author:崔金朋
* ::::``:::::::::' .:::.
* ::::' ':::::' .::::::::.
* .::::' :::: .:::::::'::::.
* .:::' ::::: .:::::::::' ':::::.
* .::' :::::.:::::::::' ':::::.
* .::' ::::::::::::::' ``::::.
* ...::: ::::::::::::' ``::.
* ```` ':. ':::::::::' ::::..
* '.:::::' ':'````..
*/
package main
import (
"fmt"
"strconv"
)
func Hannoi(num int, left, middle, right, from, to string) int {
if num < 1 {
return 0
}
return Process(num, left, middle, right, from, to)
}
func Process(num int, left, middle, right, from, to string) int {
if num == 1 {
if from == middle || to == middle {
step := "Move 1 from " + from + " to " + to
fmt.Println(step)
return 1
} else {
step1 := "Move 1 from " + from + " to " + middle
step2 := "Move 1 from " + middle + " to " + to
fmt.Println(step1)
fmt.Println(step2)
return 2
}
}
if from == middle || to == middle {
var another string
if from == left || to == left {
another = left
} else {
another = right
}
part1 := Process(num-1, left, middle, right, from, another)
part2 := 1
step := "Move " + strconv.Itoa(num) + " from " + from + " to " + to
fmt.Println(step)
part3 := Process(num-1, left, middle, right, another, to)
return part1 + part2 + part3
}
part1 := Process(num-1, left, middle, right, from, to)
part2 := 1
step1 := "Move " + strconv.Itoa(num) + " from " + from + " to " + middle
fmt.Println(step1)
part3 := Process(num-1, left, middle, right, to, from)
part4 := 1
step2 := "Move " + strconv.Itoa(num) + " from " + middle + " to " + to
fmt.Println(step2)
part5 := Process(num-1, left, middle, right, from, to)
return part1 + part2 + part3 + part4 + part5
}
接下来是栈的方式:
/*
* .::::.
* .::::::::.
* :::::::::::
* ..:::::::::::'
* '::::::::::::'
* .::::::::::
* '::::::::::::::..
* ..::::::::::::. Utils:栈求解汉诺塔游戏
* ``:::::::::::::::: Author:崔金朋
* ::::``:::::::::' .:::.
* ::::' ':::::' .::::::::.
* .::::' :::: .:::::::'::::.
* .:::' ::::: .:::::::::' ':::::.
* .::' :::::.:::::::::' ':::::.
* .::' ::::::::::::::' ``::::.
* ...::: ::::::::::::' ``::.
* ```` ':. ':::::::::' ::::..
* '.:::::' ':'````..
*/
package main
import (
"fmt"
"strconv"
)
const (
Number = iota
LeftToMiddle
MiddleToLeft
RightToMiddle
MiddleToRight
)
type HannoiStack struct {
LeftStack CommonStack
MiddleStack CommonStack
RightStack CommonStack
}
func (h *HannoiStack) HannoiGame(num int, left, middle, right string) interface{} {
h.LeftStack.CommonPush(32164)
h.MiddleStack.CommonPush(32164)
h.RightStack.CommonPush(32164)
for i := num; i > 0; i-- {
h.LeftStack.CommonPush(i)
}
retcord := []int{Number}
step := 0
for h.RightStack.CommonLen() != num+1 {
step += h.ToStack(retcord, MiddleToLeft, LeftToMiddle, left, middle, right, left, middle)
step += h.ToStack(retcord, LeftToMiddle, MiddleToLeft, left, middle, right, middle, left)
step += h.ToStack(retcord, RightToMiddle, MiddleToRight, left, middle, right, middle, right)
step += h.ToStack(retcord, MiddleToRight, RightToMiddle, left, middle, right, right, middle)
}
return step
}
func (h *HannoiStack) ToStack(retcord []int, pre, now int, left, middle, right, from, to string) int {
fromNum := h.HannoiPeek(from, left, middle, right)
toNum := h.HannoiPeek(to, left, middle, right)
if retcord[0] != pre && fromNum < toNum {
fromElement := h.HannoiPop(from, left, middle, right)
h.HannoiPush(to, left, middle, right, fromElement)
toEle := h.HannoiPeek(to, left, middle, right)
fmt.Println("Move " + strconv.Itoa(toEle) + " from " + from + " to " + to)
retcord[0] = now
return 1
}
return 0
}
func (h *HannoiStack) HannoiPeek(item, left, middle, right string) int {
if item == left {
element, _ := h.LeftStack.CommonPeek()
return element.(int)
}
if item == middle {
element, _ := h.MiddleStack.CommonPeek()
return element.(int)
}
if item == right {
element, _ := h.RightStack.CommonPeek()
return element.(int)
}
return 0
}
func (h *HannoiStack) HannoiPop(item, left, middle, right string) int {
if item == left {
element, _ := h.LeftStack.CommonPop()
return element.(int)
}
if item == middle {
element, _ := h.MiddleStack.CommonPop()
return element.(int)
}
if item == right {
element, _ := h.RightStack.CommonPop()
return element.(int)
}
return 0
}
func (h *HannoiStack) HannoiPush(item, left, middle, right string, pushItem int) bool {
if item == left {
h.LeftStack.CommonPush(pushItem)
return true
}
if item == middle {
h.MiddleStack.CommonPush(pushItem)
return true
}
if item == right {
h.RightStack.CommonPush(pushItem)
return true
}
return false
}