Go deep into the bottom! Iterative traversal and traversal of binary tree

Posted by possiblyB9 on Sat, 23 Oct 2021 16:56:42 +0200

① Traversal mode and concept of binary tree

Preorder traversal: traverse according to the head left right method, first output the head, then output the left, and finally output the right.

                According to the above figure, the preceding traversal should be: 1 > 2 > 4 > 5 > 3 > 6 > 7

                It is easy to understand the pre order, middle order and post order by distinguishing the relationship between the number in the figure above and the subtree.

                For example: 245 is the left side of the big binary tree, 367 is the right side of the big binary tree, and 4 is the left side of the decimal 245

Middle order traversal: traverse in the left head right mode, first output the left side, then the head, and finally the right side.

                According to the above figure, the middle order traversal should be: 4 > 2 > 5 > 1 > 6 > 3 > 7

Post order traversal: traverse in the way of left right head, output the left side first, then the right side, and finally the head.

                According to the above figure, the post order traversal should be: 4 > 5 > 2 > 6 > 7 > 3 > 1

② Iterative traversal of binary tree

         Iteration is commonly used in Java and other languages. Iteration has the advantages of concise and easy to understand code and closest to the underlying principle of the algorithm. However, when the sample data is too large, the iteration will produce surprising space consumption, such as Fibonacci iterative algebra column. When calculating the 100th number, the computer needs to spend a lot of time and space to do the operation, which is a huge disadvantage of the iteration. Therefore, the tool of iteration should be flexibly selected according to the actual situation of the project.

         Don't say much. Put your horse here. (Java implementation)

Preorder traversal:

         The first if judgment prevents the occurrence of extreme cases, that is, head==null.

         The following three lines are the output header, continue iteration on the left and re iteration on the right. Use the first figure for analysis: first, when head.val is 1, print out output 1, and head.left, that is, 2, starts a new round of iteration; 2 after entering the iteration, the head will be equal to 2 and 2 will be printed, and then the left side of 2, i.e. 4, will enter the third round of iteration and print 4, and both the left and right sides of 4 are null; Therefore, it will return 2 places, start the iteration on the right, print 5, and the left and right of 5 are null; Therefore, go back to the first 1, enter 3 on the right side of 1, iterate and print 3; Enter the iteration on the left side of 3, print 6, about 6 is null, and return 3; Enter the right side of 3, print 7, and about 7 is null to complete the iteration.

Therefore, the preorder traversal is 1 > 2 > 4 > 5 > 3 > 6 > 7

//Priority header > left > right
	public static void preOrderRecursive(Node head){
		if(head == null){return;}
		
		System.out.print(head.val);
		preOrderRecursive(head.left);
		preOrderRecursive(head.right);
	}

Middle order traversal:

//Middle order left > head > right
	public static void inOrderRecursive(Node head){
		if(head==null){return;}
		
		inOrderRecursive(head.left);
		System.out.print(head.val);
		inOrderRecursive(head.right);
	}

Post order traversal:

//Sequence left > right > head
	public static void posOrderRecursive(Node head){
		if(head==null){return;}
		
		posOrderRecursive(head.left);
		posOrderRecursive(head.right);
		System.out.print(head.val);
	}

③ Non iterative traversal of binary trees

        As mentioned earlier, iteration will cause a lot of space and time consumption when the data is huge. It is fatal to any project, so we make improvements to implement the logic of "iteration" with while.

Preorder traversal:

        We use the stack and the feature of first in and last out FILO to realize the head left right of the preamble. We can do the opposite, pop the head first, press it into the right and then the left (this order is very important!). Therefore, when the stack pops up, the left side will pop up first and then the right side. This is consistent with the order of head left right.

public static void preOrder(Node head){
		
		Stack<Node> stack = new Stack<>();
		stack.add(head);
		
		while(!stack.isEmpty()){
			
			head = stack.pop();//Head out first
			System.out.print(head.val);
			//Use the stack in and out feature to let the right in and then the left in
			//In this way, you can ensure that the left comes out first and the right comes out again. Complete the head > left > right preorder traversal
			if(head.right!=null)
				stack.push(head.right);
			if(head.left!=null)
				stack.push(head.left);
		}//At the end of the while loop, all stack s pop up and complete the sequence first
		
	}

Middle order traversal:

        The middle order traversal will be more complex compared with the first in and last out principle of the stack. But the judgment condition is head= null ||   ! stack.isEmpty. Let me refer to the binary tree at the beginning of the article to smooth out my ideas.

     The macro idea is: press all the left into the stack, and the pointer always follows the left element. If the pointer is empty, the stack pops up and points to the right, and then press the left (relative) of the right element cyclically. In this way, the binary tree is divided obliquely, so the order when pressing out the stack is the opposite, which is left - head - right, which is just consistent with the middle order traversal.

         Because the middle order traversal is left head right. We first create a stack. If the header is not empty, press the header, and move the head as a pointer to the left (i.e. 2) of the original position (i.e. 1). This operation is placed under while, that is, press all non null elements on the left into the stack, i.e. 1, 2 and 4, while the left side of 4 is null. Stop while if, and enter while else to release the elements at the top of the stack (at this time, the top of the stack is 4) and print 4 (at this time, it is 1 (bottom) - 2 (top) in the stack), point the head pointer to the right side of the printed element (4, the right side is null); again, in the while loop, the head is empty, enter else, print the top element of the stack, print 2 (at this time, there is only 1 in the stack), and the head pointer points to the right side of 2, 5

         The consistent loop stops until head==null and all elements pop up in the stack.

   

//Sequence traversal in binary tree left > head > right
	public static void inOrder(Node head){
		Stack<Node> stack = new Stack<>();
		while(head!=null || !stack.isEmpty()){
			if(head!=null){
				stack.push(head);
				head = head.left;
			}
			else{
				head = stack.pop();
				System.out.print(head.val);
				head = head.right;
			}
		}
	}

Post order traversal:

        The left right head is traversed in the following order. Two stacks are used. The first stack is first pressed into the head, then the left and then the right.

Then pop up the first stack in the order of head - right - left (note that the left and right are reversed when the first stack is poured out), and be received by the tail stack as head (at the bottom) - right - left. Finally, pour out the tail stack traversal, and the final order is left - right - head, that is, post order traversal.

//After traversing the left > right > head of the binary tree, an auxiliary stack is used, which only needs to be built in reverse
	public static void posOrder(Node head){
		Stack<Node> stack = new Stack<>();
		Stack<Node> helpStack = new Stack<>();
		
		stack.add(head);
		while(!stack.isEmpty()){
			head = stack.pop();
			helpStack.push(head);
			
			if(head.left!=null)
				stack.push(head.left);
			
			if(head.right!=null)
				stack.push(head.right);
		}
		while(!helpStack.isEmpty()){//Pour out the auxiliary stack
			System.out.print(helpStack.pop().val);
		}
	}

Finally, the calling method is tested

public static class Node{
		int val;
		Node left;
		Node right;
		Node(int x){
			this.val = x;
			left = null;
			right = null;
		}
	}
	
	public static void main(String[] args){
		Node head = new Node(1);
		head.left = new Node(2);
		head.right = new Node(3);
		head.left.left = new Node(4);
		head.left.right = new Node(5);
		head.right.left = new Node(6);
		head.right.right = new Node(7);
		System.out.print("Preorder traversal");
		preOrder(head);
		System.out.println();
		
		System.out.print("Medium order traversal");
		inOrder(head);
		System.out.println();
		
		System.out.print("Postorder traversal");
		posOrder(head);
		System.out.println();
	}

result

================recursive========================
pre-order:1245367
in-Order:4251637
pos-Order:4526731

Process finished with exit code 0

Topics: Java Eclipse data structure intellij-idea