Implementation example of Hanoi non-recursive algorithm

Source: Internet
Author: User

Recently, the algorithm class, referred to the recursive and divided strategy, the book on the recursive example is a very classic of the Nottingham tower problem. The main problem is that there are three tower seats, respectively, A,b,c, the beginning of the tower on a stack of n disks, these discs from top to bottom, from small to the earth stacked together, each disk from little to large numbered 1 to N. Requires that the disc on tower A be moved to Tower B, and that only one disc can be moved at a time while moving, and that the discs on each tower must be kept from top to bottom, from small to large.

This paper does not involve the mathematical proof of the non recursive algorithm, if you want to understand the truth of the recursive algorithm, the following do not need to see.

Recursive solution is no longer said, here to talk about the non recursive solution. Textbook for the non-recursive solution is described in this way:

Assuming that the tower seat a,b,c into a triangle, the a->b->c->a constitutes a clockwise cycle, in the process of moving the disk, if the odd number of times to move, the smallest disc to move clockwise to the next tower; If you move occasionally, keep the smallest disc motionless, And between the other two towers, the smaller discs are moved to the other tower seat.
Here we default tower A is the initial disc placed in the tower seat, Tower B is the disk needs to move to the target tower, Tower C is the target tower, N is the initial number of discs. After the personal code verification, confirmed that the book said a little wrong, the correct statement is:

When n is odd, the tower seats are arranged in A->b->c->a, and when N is an even number, the tower should be arranged in A->c->b->a.

Their own coding, but also the internet to read other people write code, they are not very like, defined a variety of complex structures and functions, and so on, so they wrote a C + + version, only used vector this kind of data structure, but because they are written in a Hanoi function body, About printing information may not be handled very well, it appears that the program is a bit verbose, but the overall structure is quite clear. The code is as follows:

The code is as follows Copy Code

void Hanoi (int n) {
The aim is to move plates from A to B
When n is odd, the tower was placed in order A->b->c
When n is even, the tower was placed in order A->c->b
vector<char> odd{' A ', ' B ', ' C '};
vector<char> even{' A ', ' C ', ' B '};
Vector<vector<int>> Tower (3, vector<int> ());

Initialize
for (int i=n; i>=1; i--)
Tower[0].push_back (i);

Loop begin
int iter = 0;
while (true) {
Different endings for n
if (n%2 && tower[0].empty () && tower[2].empty ()) break;
if (n%2==0 && tower[0].empty () && tower[1].empty ()) break;

iter++;

if (iter% 2) {//Odd plate move
Just move plate1 to next tower
int min = max+1;
int index;
for (int i=0; i<3; i++) {
if (!tower[i].empty () && tower[i].back () <min) {
min = Tower[i].back ();
index = i;
}
}
Tower[index].pop_back ();
tower[(index+1)%3].push_back (min);

if (n%2) {//different n, different messages
cout << "Moving plate" << min << "from"
<< Odd[index] << "to"
<< odd[(index+1)%3] << Endl;
}
else {
cout << "Moving plate" << min << "from"
<< Even[index] << "to"
<< even[(index+1)%3] << Endl;
}
}
else {//even plate move
Move the smallest plate except plate1 to another
int min = max+1;
int index;
for (int i=0; i<3; i++) {
if (!tower[i].empty () && tower[i].back () <min) {
min = Tower[i].back ();
index = i;
}
}
Get the "other two tower whose" is not plate1
int index1 = (index+1)%3;
int index2 = (index+2)%3;
if (Tower[index1].empty ()) {
min = Tower[index2].back ();
Tower[index2].pop_back ();
Tower[index1].push_back (min);

if (n%2) {//different n, different messages
cout << "Moving plate" << min << "from"
<< Odd[index2] << "to"
<< Odd[index1] << Endl;
}
else {
cout << "Moving plate" << min << "from"
<< Even[index2] << "to"
<< Even[index1] << Endl;
}
}
else if (Tower[index2].empty ()) {
min = Tower[index1].back ();
Tower[index1].pop_back ();
Tower[index2].push_back (min);

if (n%2) {//different n, different messages
cout << "Moving plate" << min << "from"
<< Odd[index1] << "to"
<< Odd[index2] << Endl;
}
else {
cout << "Moving plate" << min << "from"
<< Even[index1] << "to"
<< Even[index2] << Endl;
}
}
else {
int index3;
if (Tower[index1].back () < Tower[index2].back ()) {
min = Tower[index1].back (); Index3 = index1;
}
else {
min = Tower[index2].back (); Index3 = Index2;
}
Tower[index3].pop_back ();
Tower[3-index-index3].push_back (min);

if (n%2) {//different n, different messages
cout << "Moving plate" << min << "from"
<< Odd[index] << "to"
<< odd[(index+1)%3] << Endl;
}
else {
cout << "Moving plate" << min << "from"
<< Even[index] << "to"
<< even[(index+1)%3] << Endl;
}
}
}
}
Return
}

The two vectors defined in the 5, 62 lines of the above code are used when printing information. When n is odd, we use the order inside the odd, n is even, use the order of the even inside, all print processing information to take into account the parity of N, it appears that the printing of information that a few places more wordy. The disk information on each tower is recorded using only a two-dimensional vector tower, when initialized tower[0], that is, the tower a above the bottom from the big to small placed n disk.

Then it goes into the loop, and because of the parity problem of N, there are two ways to determine the termination cycle, in line 17th and 18. The entry loop is divided into two large chunks, that is, whether the current move is an odd number of times or even several times, if it is the odd number of times, the execution of the 22 line start code, will be labeled 1 disk clockwise to the next tower, to consider the parity of N to bring the different clockwise order of different problems; if it is even several times, the start of 46 lines of code , keep the smallest disc motionless, move the other two tower seats on the smaller disc to another tower, here to determine whether the two towers do not exist in the disc, the same is to consider the parity of n brought about by a different clockwise order.

Make some improvements later

The code is as follows Copy Code

#include <iostream>
#include <vector>
using namespace Std;

const int MAX = 64;

void Hanoi (int n) {
The aim is to move plates from A to B
When n is odd, the tower was placed in order A->b->c
When n is even, the tower was placed in order A->c->b
vector<char> odd{' A ', ' B ', ' C '};
vector<char> even{' A ', ' C ', ' B '};
Vector<vector<int>> Tower (3, vector<int> ());

Initialize
for (int i=n; i>=1; i--)
Tower[0].push_back (i);

Loop begin
int iter = 0;
while (true) {
Different endings for n
if (n%2 && tower[0].empty () && tower[2].empty ()) break;
if (n%2==0 && tower[0].empty () && tower[1].empty ()) break;

iter++;

if (iter% 2) {//Odd plate move
Just move plate1 to next tower
int min = max+1;
int index;
for (int i=0; i<3; i++) {
if (!tower[i].empty () && tower[i].back () <min) {
min = Tower[i].back ();
index = i;
}
}
Tower[index].pop_back ();
tower[(index+1)%3].push_back (min);

if (n%2) {//different n, different messages
cout << "Moving plate" << min << "from"
<< Odd[index] << "to"
<< odd[(index+1)%3] << Endl;
}
else {
cout << "Moving plate" << min << "from"
<< Even[index] << "to"
<< even[(index+1)%3] << Endl;
}
}
else {//even plate move
Move the smallest plate except plate1 to another
int min = max+1;
int index;
for (int i=0; i<3; i++) {
if (!tower[i].empty () && tower[i].back () <min) {
min = Tower[i].back ();
index = i;
}
}
Get the "other two tower whose" is not plate1
int index1 = (index+1)%3;
int index2 = (index+2)%3;
if (Tower[index1].empty ()) {
min = Tower[index2].back ();
Tower[index2].pop_back ();
Tower[index1].push_back (min);

if (n%2) {//different n, different messages
cout << "Moving plate" << min << "from"
<< Odd[index2] << "to"
<< Odd[index1] << Endl;
}
else {
cout << "Moving plate" << min << "from"
<< Even[index2] << "to"
<< Even[index1] << Endl;
}
}
else if (Tower[index2].empty ()) {
min = Tower[index1].back ();
Tower[index1].pop_back ();
Tower[index2].push_back (min);

if (n%2) {//different n, different messages
cout << "Moving plate" << min << "from"
<< Odd[index1] << "to"
<< Odd[index2] << Endl;
}
else {
cout << "Moving plate" << min << "from"
<< Even[index1] << "to"
<< Even[index2] << Endl;
}
}
else {
int index3;
if (Tower[index1].back () < Tower[index2].back ()) {
min = Tower[index1].back (); Index3 = index1;
}
else {
min = Tower[index2].back (); Index3 = Index2;
}
Tower[index3].pop_back ();
Tower[3-index-index3].push_back (min);

if (n%2) {//different n, different messages
cout << "Moving plate" << min << "from"
<< Odd[index] << "to"
<< odd[(index+1)%3] << Endl;
}
else {
cout << "Moving plate" << min << "from"
<< Even[index] << "to"
<< even[(index+1)%3] << Endl;
}
}
}
}
Return
}

int main () {
int n;
while (CIN >> N) {
Hanoi (n);
}
return 0;
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.