lẽ là giải pháp đơn giản nhất để Towers Hà Nội làm việc như thế này:
Để di chuyển x
đĩa từ peg A đến peg C, sử dụng peg B như một "aux" peg:
- Move
x-1
đĩa từ chốt A đến chốt B, sử dụng chốt C làm chốt móc.
- Di chuyển
x
đĩa thứ hai từ cọc A sang cọc C (không cần chốt móc, vì bạn chỉ di chuyển một đĩa).
- Di chuyển các đĩa
x-1
từ giá peg B sang giá trị C, sử dụng giá trị peg A làm giá đỡ aux.
Lưu ý rằng để di chuyển x
đĩa, bạn phải di chuyển x-1
đĩa. Bạn chỉ có thể sử dụng cùng một chức năng để di chuyển các đĩa x-1
này và chỉ chuyển đổi các chốt là nguồn, đích và chốt aux. Đó là điều làm cho Towers of Hanoi trở thành một ví dụ phổ biến về đệ quy, và đó là kiểu mẫu mà bạn cần thấy trong một vấn đề để làm cho công việc đệ quy cho bạn. Nó không cần phải "di chuyển x-1
đĩa", tất nhiên ... nó có thể là một cái gì đó như "danh sách thư mục con này". Cây (giống như một thư mục với thư mục con và như vậy) là một nơi mà đệ quy tỏa sáng. Cũng giống như các công việc khác, nơi để thực hiện công việc trên một mục, bạn có thể cần thực hiện cùng một công việc trên các mục con.
Bây giờ, để có đệ quy hữu ích, bạn cần "trường hợp cơ sở" - điều kiện nơi đệ quy sẽ dừng lại. Nếu bạn không, mã sẽ chạy mãi mãi (hoặc ít nhất là nó sẽ hết bộ nhớ hoặc tràn ngăn xếp cuộc gọi). Trường hợp cơ sở ở đây xảy ra khi x == 0
(vì di chuyển 0 đĩa nghĩa là bạn không làm gì, do if
xung quanh thịt của hàm). Nó cũng có thể là khi x == 1
, như sau đó bạn không phải recurse, nhưng thêm if
trước khi mỗi cuộc gọi hanoi
sẽ thêm một chút tiếng ồn (và lợi ích chính cho một giải pháp đệ quy là sự đơn giản của nó). Dù sao, khi x == 0
, hàm trả về mà không làm bất cứ điều gì. Hàm được gọi là nó (có x == 1
) bây giờ được tiếp tục làm việc của nó - trong trường hợp này, nói "di chuyển đĩa 1 từ src đến dest", và sau đó gọi hàm hanoi
một lần nữa với các chuyển đổi args.
Dòng chảy đi một chút như thế này:
hanoi(3, src, aux, dest)
hanoi(2, src, dest, aux)
hanoi(1, src, aux, dest)
hanoi(0, src, dest, aux) // no op
print "Move 1 from src to dest"
hanoi(0, aux, src, dest) // no op
print "Move 2 from src to aux"
hanoi(1, dest, src, aux)
hanoi(0, dest, aux, src) // no op
print "move 1 from dest to aux"
hanoi(0, src, dest, aux) // no op
print "move 3 from src to dest"
hanoi(2, aux, src, dest)
hanoi(1, aux, dest, src)
hanoi(0, aux, src, dest) // no op
print "Move 1 from aux to src"
hanoi(0, dest, aux, src) // no op
print "Move 2 from aux to dest"
hanoi(1, src, aux, dest)
hanoi(0, src, dest, aux) // no op
print "move 1 from src to dest"
hanoi(0, aux, src, dest) // no op
thể trùng lặp của [chức năng hanoi Crockford (từ "The Good Parts")] (http: // stackoverflow.com/questions/3742305/crockfords-hanoi-function-from-the-good-parts) –
Bạn đã đọc http://en.wikipedia.org/wiki/Tower_of_Hanoi#Recursive_solution chưa? –
Ngoài ra: http://stackoverflow.com/questions/7061030/tower-of-hanoi-javascript-the-good-parts?rq=1 – kapa