On the Tower of Hanoi


Regarding the Tower of Hanoi question, just express what you think. If there is something wrong, please correct me! ! !

What is the Tower of Hanoi?

The Tower of Hanoi, also known as the Tower of Hanoi, is an educational toy derived from ancient Indian legends. When the Brahma created the world, he made three diamond pillars. On one pillar, 64 golden discs were stacked in order of size from bottom to top. The Great Brahma ordered the Brahmin to re-place the disc on another pillar in order of size from below. It is also stipulated that the disc cannot be enlarged on the small disc, and only one disc can be moved between the three pillars at a time.

1. Ideas for Solving the Tower of Hanoi Problem

Suppose there are three pillars and a total of four discs, as shown in the figure:
Insert picture description here

If you want to put the four discs on the A-pillar on the C-pillar in the same order, you must use the B-pillar, and only one disc can be taken at a time. Therefore, two situations will occur during the moving process, namely From the bottom to the top, there will be from big to small and from small to big.
Step 1: Put the three largest discs on the A-pillar on the B-pillar, and then put the largest disc on the A-pillar on the C-pillar.
Insert picture description here

Step 2: After completing the first step, the A column is vacant, and with the aid of the A column, put the two pieces of the B column except the bottom disc on the A column, and place the bottom of the B column Place the disc on the C-pillar.
Insert picture description here

The third step: After completing the second step, empty the B-pillar. With the help of the B-pillar, place the other wafer of the A-pillar except the bottom wafer on the B-pillar, and place the bottom wafer of the A-pillar Put it on the C-pillar.
Insert picture description here
Step 4: Place the last wafer on the B-pillar on the A-pillar.
Insert picture description here
This completes the placement of the wafers on the A pillar on the C pillar in the same order.

2. Code implementation of the Tower of Hanoi problem

If you want to solve the problem of the Tower of Hanoi, you must find the law and find the idea to solve the problem.
We can imagine the three columns as three arrays, namely arr1, arr2, and arr3. During the
Insert picture description here
whole process, only the A and B columns are used to move. The C column is not involved. The C column just puts the wafers in sequence.
Follow the above steps, as shown below
Insert picture description here

First time:
for arr1 and arr2:
arr1[3] ===> arr2[0]
arr1[2] ===> arr2[1]
arr1[1] ===> arr2[2]
for arr3:
arr1[ 0] ===> arr3[0]

Insert picture description here

Second time:
For arr1 and arr2:
arr2[1] ===> arr1[0]
arr2[0] ===> arr1[1]
For arr3:
arr2[2] ===> arr3[1]
Insert picture description here

The third time:
for arr1 and arr2:
arr1[1] ===> arr2[0]
for arr3:
arr1[0] ===> arr3[2]
Insert picture description here

arr2[0] ===> arr3[3]

For the last time, there is only one wafer left, which can be directly placed on the C-pillar, namely arr3.

Summarize the law

1. In the movement, only arr1 and arr2 are used, so the moving part only needs to design the arr1 and arr2 arrays, and every time you move, one of arr1 and arr2 will become empty.
2. The C column, which is the position where arr3 is placed, will increase by one.
3. In the process of moving, there will be two different situations, so it is necessary to design different placement methods in the moving function.

3. Code implementation

According to the above ideas and the rules summarized, since the process of each movement is almost the same, I think recursion can be used to realize the process of the Tower of Hanoi, and the two most important conditions in the recursion:
1. The restriction condition is the ability to move The number of discs, when the disc is 0, it means that the movement is completed
. 2. Every time the function is called, the number of discs is reduced by one, so as to continuously approach the restriction conditions.

The code is implemented as follows:

1. Main function code

#include "hanoi.h"
int main()
{
    
    
	int i = 0;
	int arr1[SIZE] = {
    
    4, 3, 2, 1 };
	int arr2[SIZE] = {
    
     0 };
	int arr3[SIZE] = {
    
     0 };
	Hanoi(arr1, arr2, arr3,SIZE);
	print(arr1);
	print(arr2);
	print(arr3);
	return 0;
}

I defined 3 arrays in the main function, arr1 represents the A column, arr2 represents the B column, arr3 represents the C column. In
arr1, 4 represents the largest disc, and 1 represents the smallest disc, that is, from bottom to top. Decrease.
SIZE defines the number of wafers.

2.Hanoi function

The Hanoi function is used to implement the entire Hanoi Tower process.

void Hanoi(int* arr1, int* arr2, int* arr3, int sum)
{
    
    
	if (sum > 1)
	{
    
    

		if (*arr2 == 0)
		{
    
    
			move2(arr1, arr2, arr3, sum);
			clear(arr1);
			Hanoi(arr1, arr2, arr3 + 1, sum - 1);
		}
		else if (*arr1 == 0)
		{
    
    
			move1(arr1, arr2, arr3, sum);
			clear(arr2);
			Hanoi(arr1, arr2, arr3 + 1, sum - 1);
		}
	}
	else
	{
    
    
		if (*arr1 != 0)
		{
    
    
			*arr3 = *arr1;
			clear(arr1);
		}
		else if (*arr2 != 0)
		{
    
    
			*arr3 = *arr2;
			clear(arr2);
		}
	}
}

The restriction is the number of movable discs, which is represented by sum in the Hanoi function.
The if condition here is set to be greater than 1 because when the number of wafers is only one, it can be directly placed in arr3, which is a special case, and when the number is greater than 1, recursion continues.
After the judgment is true, it is necessary to judge which array is empty to move with this array. This is why the empty array is initialized to 0 in the main function, just for the convenience of judgment here. Because the parameter passed in the past is the address of the first element of the array, but because the entire array is initialized to 0, you can know which array is empty by judging whether the first element is 0.

Note: There are two changes in each recursive function:
1. The position of arr3 is incremented by one each time, because arr3 will be placed after each movement, so its position must be updated every time it is called.
2. The value of sum is reduced by one each time, because after each movement, the number of movable discs will be reduced by one, constantly approaching the limit.

3.move1 and move2 functions

void move2(int* arr1, int* arr2, int* arr3, int sum)
{
    
    
	int i = 0;
	if (*arr1 > *(arr1 + 1))
	{
    
    
		for (i = sum - 1; i >= 1; i--)
		{
    
    
			*(arr2 + sum - i - 1) = *(arr1 + i);
		}
		*arr3 = *arr1;

	}
	else if (*arr1 < *(arr1 + 1))
	{
    
    
		for (i = sum - 1; i >= 1; i--)
		{
    
    
			*(arr2 + sum - i - 1) = *(arr1 + i-1);
		}
		*arr3 = *(arr1 + sum - 1);
	}
}

void move1(int* arr1, int* arr2, int* arr3, int sum)
{
    
    

	int i = 0;
	if (*arr2 > *(arr2 + 1))
	{
    
    
		for (i = sum - 1; i >= 1; i--)
		{
    
    
			*(arr1 + sum - i - 1) = *(arr2 + i);
		}
		*arr3 = *arr2;

	}
	else if (*arr2 < *(arr2 + 1))
	{
    
    
		for (i = sum - 1; i >= 1; i--)
		{
    
    
			*(arr1 + sum - i - 1) = *(arr2 + i-1);
		}
		*arr3 = *(arr2 + sum - 1);
	}
}

The move1 function uses arr1 to move when the arr1 array is empty.
In the move2 function, when the arr2 array is empty, move with the help of arr2.
According to the rules summarized above, judge the placement of the wafer before each movement. From small to large is a rule, and from large to small is another rule; judge before moving.

4.clear function

void clear(int* arr)
{
    
    
	int i = 0;
	for (i = 0; i < SIZE; i++)
	{
    
    
		*(arr + i) = 0;
	}
}

This part is placed after the move1 and move2 functions. The purpose of this function is to clear the empty array after the move to facilitate the next judgment.

I found in the summary rule that if the arr1 array is used when starting to move, the arr2 array will be empty after the move; if the arr2 array is used when the move is started, then the arr1 array will be empty after the move. According to this rule , I clear arr2 after the move1 function; clear arr1 after the move2 function, so that it will be very convenient for the next judgment.

5.print function

void print(int* arr)
{
    
    
	int i = 0;
	for (i = 0; i < SIZE; i++)
	{
    
    
		printf("%d ", *(arr + i));
	}
	printf("\n");
}

This function is to print three arrays at the end to see if the whole problem is solved.

operation result:
Insert picture description here

Insert picture description here

Four. Summary

According to the code for completing the Tower of Hanoi problem, I have a deeper understanding of this part of recursion. When writing recursion, we must pay attention to two necessary conditions, and the problems that can be solved by recursion must be regular. Yes, if the recursive writing becomes more troublesome, it must be wrong. Writing code is more about thinking. You have to conceive it in your head first, and then write it with your hands. This time the program implementation gave me great gains.

Guess you like

Origin blog.csdn.net/qq_41490958/article/details/113084091