definition
If a binary sort tree of {1,2,3,4,5,6}, its left subtree is empty, and each node is stacked on the right subtree. It looks more like a single linked list. Although its insertion speed has no impact, the query speed is significantly reduced (because it needs to be compared in turn), which can not give full play to the query advantages of BST.
The solution is AVL balanced binary tree
Balanced binary tree, also known as AVL tree, is a special kind of tree Binary sort tree . AVL tree is either an empty tree or a binary tree with the following properties:
(1) Both the left subtree and the right subtree are balanced binary trees;
(2) The absolute value of the difference between the depth (height) of the left subtree and the right subtree shall not exceed 1.
Application case - single rotation (left rotation)
First, get the height of the left and right subtrees and the root node itself
/** * Returns the height of the left and right subtrees where the node is the root node * @return */ public int leftHeight(){ if (left == null){ return 0; }else { return left.height(); } } public int rightHeight(){ if (right == null){ return 0; }else { return right.height(); } } /** * Returns the height of the current node and the height of the tree with this node as the root node * @return */ public int height(){ //Recursion from both sides //Why add one? Because it only counts the height of the left subtree and the right subtree, it is also a layer, so add one return Math.max(left == null ? 0:left.height(), right == null ? 0 : right.height())+1; }
/** * AVL When the left rotation of the tree is placed to add nodes, if the height of the right subtree - the height of the left subtree > 1, the left rotation is called */ private void leftRotate(){ //Create a new node with the value of the current root node Node temp = new Node(this.value); //Set the left subtree of the new node as the left subtree of the current node temp.left = this.left; //Set the right subtree of the new node to the left subtree of the right subtree of the current node temp.right = this.right.left; //Replace the value of the current node with the value of the right child node this.value = this.right.value; //Set the right subtree of the current node as the right subtree of the right subtree this.right = this.right.right; //Set the left subtree of the current node as a new node this.left = temp; }
/** * Add nodes recursively, provided that the requirements of AVL tree are met * * @param node */ public void add(Node node) { if (node == null) { return; } //Judge the relationship between the value of the incoming node and the value of the root node of the current subtree if (node.value < this.value) { //If the left child node of the current node is empty, the node is directly attached to the left child node of the current node if (this.left == null) { this.left = node; } else { //Recursively add to the left subtree this.left.add(node); } } else { //The value of the added node is greater than the value of the current node if (this.right == null) { //Hang the current value on the right child node this.right = node; } else { //Recursive right addition this.right.add(node); } } //If the height of the right subtree - the height of the left subtree > 1, the left rotation is called if (rightHeight() - leftHeight() > 1){ leftRotate(); } }
You can see that the balance is complete
Application case - single rotation (right rotation)
/** * AVL Right rotation of the tree. When adding nodes, if the height of the left subtree - the height of the right subtree is > 1, the right rotation is called */ private void rightRotate(){ //Create a new node with the value of the current root node Node temp = new Node(this.value); //The right child node of the new node points to the right child node of the current node temp.right = this.right; //The left child node of the new node points to the right child node of the left child node of the current node temp.left = this.left.right; //Replace the value of the current node with the value of the left child node this.value = this.left.value; //Replace the left child node of the current node with the left child node of the left child node this.left = this.left.left; //Replace the right child node of the current node with a new node this.right = temp; }
Application case - double rotation
When the conditions for right rotation are met
If the height of the right subtree of his left subtree is greater than that of its left subtree
Rotate the left node first
Then right rotate the current node
/** * Add nodes recursively, provided that the requirements of AVL tree are met * * @param node */ public void add(Node node) { if (node == null) { return; } //Judge the relationship between the value of the incoming node and the value of the root node of the current subtree if (node.value < this.value) { //If the left child node of the current node is empty, the node is directly attached to the left child node of the current node if (this.left == null) { this.left = node; } else { //Recursively add to the left subtree this.left.add(node); } } else { //The value of the added node is greater than the value of the current node if (this.right == null) { //Hang the current value on the right child node this.right = node; } else { //Recursive right addition this.right.add(node); } } //If the height of the right subtree - the height of the left subtree > 1, the left rotation is called if (rightHeight() - leftHeight() > 1){ //If the height of the left subtree of the right subtree of the current node is greater than the height of the right subtree of the current node if (this.right.leftHeight() > this.right.rightHeight()){ //First rotate the right subtree of the current node right.rightRotate(); } leftRotate(); return; } //If the height of the left subtree - the height of the right subtree > 1, the right rotation is called //Add a double rotation condition: if the height of the right subtree of the left subtree of the current node is greater than the height of the left subtree of the current node if (leftHeight() - rightHeight() > 1){ //If the height of the left subtree and the right subtree of the current node is greater than the height of the left subtree of the current node if (this.left.rightHeight() > this.left.leftHeight()){ //First rotate the left subtree of the current node left.leftRotate(); } //Rotate right subtree rightRotate(); } }
The balanced binary tree is created