Traversal search of binary search tree (Java implementation)

1. The concept of
binary search tree A binary search tree is organized by a binary tree. Such a tree can be represented by a linked list data structure, where each node is an object.
Insert picture description here

2. The attributes of the binary search tree node object
(1) key (keyword, used to represent the entire object)
(2) Basic data and information
(3) left, right and p, respectively pointing to the left child node of the node , Right child node, parent node (if the parent node is used less, it can be omitted)

 class TreeNode {
    
    
      int key; //关键字
      TreeNode left; //左节点
      TreeNode right;  //右节点
      TreeNode() {
    
    }
      TreeNode(int val) {
    
     this.val = val; }
      TreeNode(int val, TreeNode left, TreeNode right) {
    
    
          this.val = val;
          this.left = left;
          this.right = right;
      }
  }

3. The most basic construction rules of binary search tree
For any node node, the key of each node of the left subtree cannot be greater than node.key, and the key of each node of the right subtree cannot be less than node.key . This construction rule can lead to a property of the binary search tree-if childNode is a node on the left subtree of node, then childNode.key<=node.key, similarly, if it is on the right subtree, then childNode.key>=node.key.

4. Traversal of binary tree search
(1) There are two main methods for traversal of binary tree, which are BFS breadth search traversal and DFS deep search traversal. The core of breadth search traversal is the application of the data structure of queues; deep search traversal has There are two ways, one is to traverse through the design of recursive function, and the other is to use the stack data structure to traverse

1>DFS

//递归遍历
 public void search(TreeNode root){
    
    
        
        if(root==null)
           return;
        search(root.left);
        search(root.right);
    }
  //利用栈进行遍历
  public void search(TreeNode root){
    
    
     public void search(TreeNode root) {
    
    
        TreeNode node = root;
        Stack<TreeNode> DFS = new Stack<>();
        while (!DFS.isEmpty() || node != null) {
    
    
            while (node != null) {
    
    
                DFS.push(node);
                node = node.left;
            }
            node = DFS.pop().right;
        }
    }
 }

2>BFS

 //利用队列进行遍历
 public void search(TreeNode root){
    
    
        TreeNode node=root;
        Queue<TreeNode>DFS=new LinkedList<>();
        DFS.offer(node);
        while(!DFS.isEmpty()||node!=null){
    
    
            node=DFS.poll();
            if(node.left!=null) 
                DFS.offer(node.left);
            if(node.right!=null) 
                DFS.offer(node.right);
        }

}

(2) Advanced algorithm of binary tree traversal: Morris algorithm. The Morris algorithm greatly reduces the space complexity of traversing the binary search tree. The algorithm mainly uses a large number of empty nodes that must exist in the binary search tree (the end nodes must have empty nodes), saving the stack Or queue.

The main steps of the algorithm:

1>. For the child node of the binary search tree, if node has no left child, visit the right child of node, if node has a left child, find the rightmost node on the left subtree of node (ie in the left subtree of node) The last node of the sequence traversal) is recorded as morrisBack.

2>. According to whether the right child of morrisBack is empty, perform the following operations-if the right child is empty, point its right child to node and then visit the left child; if the right child is not empty, it means that we have traversed the node For the left subtree, we leave the right child of morrisBack empty (in order not to destroy the structure of the binary search tree), and then visit the right child of node (return to the head node of the subtree or visit the right node)

3>. Repeat the above operations until the complete tree is visited.

Morris algorithm diagram:
source of pictures
Insert picture description here

class Solution {
    
    
    public void Search(TreeNode root) {
    
    
        TreeNode node=root;
        TreeNode morrisBack;
        while(node!=null){
    
    
            
            if(node.left!=null){
    
    
                morrisBack=node.left;
               
                while(morrisBack.right!=null&&morrisBack.right!=node)
                    morrisBack=morrisBack.right;
                
                if(morrisBack.right==null){
    
    
                    morrisBack.right=node;
                    node=node.left;
                }
                else{
    
    
                    morrisBack.right=null;
                    node=node.right;
                }
            }
            
            else
                node=node.right;


        }

    }
}

5. Traversal classification of
binary tree The traversal algorithm of binary tree has three special forms, which are pre-order traversal, middle-order traversal, and subsequent traversal.
For the pre-order traversal, it means that for the current node, the node is visited first, then his left child, and finally his right child.
For in-order traversal, for the current node, first visit its left child, then visit the node, and finally visit its right child. (For a binary search tree, the middle-order traversal is accessed in the ascending order of the key value of the node, and an array in ascending order of the key value of the node can be obtained.)
For the subsequent traversal, it is for the current node first Visit its left child, then its right child, and finally the node.
Insert picture description here
Take the binary search tree in the above figure as an example:

Preorder traversal:

//递归算法
class Solution {
    
    
    public void search(TreeNode root) {
    
    
        if(root ==null)
            return;
        System.out.print(root.val+" ");
        search(root.left);
        search(root.right);
    }
}
//非递归算法
 public void search(TreeNode root) {
    
    
        TreeNode node = root;
        Stack<TreeNode> DFS = new Stack<>();
        while (!DFS.isEmpty() || node != null) {
    
    
            while (node != null) {
    
    
                System.out.print(node.val+" ");
                DFS.push(node);
                node = node.left;
            }
            node = DFS.pop().right;
        }
    }

Output result: 6 5 2 5 7 9 8

In-order traversal:

//递归算法
class Solution {
    
    
    public void search(TreeNode root) {
    
    
        if(root ==null)
            return;
        search(root.left);
        System.out.print(root.val+" ");
        search(root.right);
    }
}
//非递归算法
 public void search(TreeNode root) {
    
    
        TreeNode node = root;
        Stack<TreeNode> DFS = new Stack<>();
        while (!DFS.isEmpty() || node != null) {
    
    
            while (node != null) {
    
    
                DFS.push(node);
                node = node.left;
            }
            node = DFS.pop();
            System.out.print(root.val+" ");
            node=node.right; 
        }
    }

Output result: 2 5 5 6 7 8 9

Post-order traversal:

//递归算法
class Solution {
    
    
    public void search(TreeNode root) {
    
    
        if(root ==null)
            return;
        search(root.left);
        search(root.right);
        System.out.print(root.val+" ");
    }
}
//非递归算法
public void search(TreeNode root) {
    
    
        HashMap<TreeNode,Integer>check=new HashMap<>();
        TreeNode node = root;
        Stack<TreeNode> DFS = new Stack<>();
        while (!DFS.isEmpty() || node != null) {
    
    
            while (node != null) {
    
    
                check.put(node,1);
                DFS.push(node);
                node = node.left;
            }

            node=DFS.peek();
            if(check.get(node)==1){
    
    
                check.put(node,2);
                node=node.right;
            }
            else{
    
    
                DFS.pop();
                System.out.print(node.val+" ");
                node=null; 
            }
        }
    }

Output result: 2 5 5 8 9 7 6

Guess you like

Origin blog.csdn.net/CY2333333/article/details/107882185