# Binary sort tree

Requirements: for a sequence (7, 3, 10, 12, 5, 1, 9), it is required to query and add data efficiently

Basic introduction:
Binary sort tree: BST: (Binary Sort(Search) Tree). For any non leaf node of the binary sort tree, the value of the left child node is required to be smaller than that of the current node, and the value of the right child node is required to be larger than that of the current node.

Special note: if you have the same value, you can put this node on the left child node or the right child node

For example, for the previous data (7, 3, 10, 12, 5, 1, 9), the corresponding binary sort tree is: ## Binary sort tree creation and traversal

An array is created into the corresponding binary sort tree, and the middle order is used to traverse the binary sort tree

```package com.atguigu.binarysorttree;

/**
* @ClassName BinarySortTreeDemo
* @Author Jeri
* @Date 2022-02-26 17:58
* @Description Creation, traversal and deletion of binary sort tree
*/

//Create node class object
class Node{
int value;
Node left;
Node right;

public Node(int value){
this.value = value;
}

//Override toString method

@Override
public String toString() {
return "Node{" +
"value=" + value +
'}';
}

//Middle order traversal
public void infixOrder(){
if(this.left != null){
this.left.infixOrder();
}

System.out.println(this);

if(this.right != null){
this.right.infixOrder();
}
}

public void add(Node node){
//Handling special situations
if(node == null){ return; }

//Judge node Value and this Value size relationship
if(this.value > node.value){
//Look left
if(this.left == null){
this.left = node;
}else{
}
}else{
//Look right
if(this.right == null){
this.right = node;
}else{
}
}
}

}

//Create a binary sort tree management node
class BinarySortTree{
private Node root;

public Node getRoot() {
return root;
}

public void setRoot(Node root) {
this.root = root;
}

//Add node to binary tree
public void add(Node node){
if(root == null){
this.root = node;
}else{
}
}

//Order traversal in binary tree
public void infixOrder(){
if(this.root != null){
this.root.infixOrder();
}else{
System.out.println("Empty tree cannot be traversed");
}
}

}
public class BinarySortTreeDemo {
public static void main(String[] args) {
int[] array = new int[]{7, 3, 10, 12, 5, 1, 9};

//Create a binary tree object
BinarySortTree bst = new BinarySortTree();
for(Integer temp:array){
}

//Middle order traversal
System.out.println("Middle order traversal:----");
bst.infixOrder();

}
}

```
```Middle order traversal:----
Node{value=1}
Node{value=3}
Node{value=5}
Node{value=7}
Node{value=9}
Node{value=10}
Node{value=12}
```

## Binary sort tree deletion

The deletion of binary sort tree is complex. There are three situations to consider:

• Delete leaf node
• Delete a node with only one subtree
• Delete a node with two subtrees

Train of thought analysis:

Delete leaf node

• You need to find the targetNode of the node to be deleted first
• Find the parent node of targetNode
• Determine whether the targetNode is the left child node or the right child node of the parent
• Delete according to the previous situation

Delete a node with only one subtree

• You need to find the targetNode of the node to be deleted first
• Find the parent node of targetNode
• Determines whether the child node of the targetNode is a left child node or a right child node
• Determines whether the child node of the targetNode is a left child node or a right child node
• Delete according to the previous situation

Delete a node with two subtrees

• You need to find the targetNode of the node to be deleted first
• Find the parent node of targetNode
• Find the smallest node from the right subtree of targetNode
• Use a temporary variable to save the value of the smallest node to temp
• Delete the minimum node
• Assign the value of temp to targetNode
```package com.atguigu.binarysorttree;

/**
* @ClassName BinarySortTreeDemo
* @Author Jeri
* @Date 2022-02-26 17:58
* @Description Creation, traversal and deletion of binary sort tree
*/

//Create node class object
class Node{
int value;
Node left;
Node right;

public Node(int value){
this.value = value;
}

//Override toString method

@Override
public String toString() {
return "Node{" +
"value=" + value +
'}';
}

//Middle order traversal
public void infixOrder(){
if(this.left != null){
this.left.infixOrder();
}

System.out.println(this);

if(this.right != null){
this.right.infixOrder();
}
}

public void add(Node node){
//Handling special situations
if(node == null){ return; }

//Judge node Value and this Value size relationship
if(this.value > node.value){
//Look left
if(this.left == null){
this.left = node;
}else{
}
}else{
//Look right
if(this.right == null){
this.right = node;
}else{
}
}
}

//Find the node to be deleted
public Node search(int value){
if(this.value == value){
return this;
}else if(this.value > value){
//Left recursive search
if(this.left == null){
return null;
}
return this.left.search(value);
}else{
//Recursive right
if(this.right == null){
return null;
}

return this.right.search(value);
}
}

//Find the parent node of the node to be deleted
public Node searchParent(int value){
//Judge the current node
if((this.left != null && this.left.value == value) ||
(this.right != null && this.right.value == value)){
return this;
}else{
//The left child node of the current node is not empty and the value is greater than the lookup value
if(this.left != null && this.value > value){
return this.left.searchParent(value);
}else if(this.right != null && this.value < value){
//The right child node of the current node is not empty and the value is less than the lookup value
return this.right.searchParent(value);
}else{
return  null;
}
}
}

}

//Create a binary sort tree management node
class BinarySortTree{
private Node root;

public Node getRoot() {
return root;
}

public void setRoot(Node root) {
this.root = root;
}

//Add node to binary tree
public void add(Node node){
if(root == null){
this.root = node;
}else{
}
}

//Order traversal in binary tree
public void infixOrder(){
if(this.root != null){
this.root.infixOrder();
}else{
System.out.println("Empty tree cannot be traversed");
}
}

//Binary tree to find the node to be deleted
public Node search(int value){
if(root == null){
return null;
}else{
return this.root.search(value);
}
}

//Parent tree of node to be deleted
public Node searchParent(int value){
if(root == null){
return null;
}else{
return this.root.searchParent(value);
}
}

//Binary tree finds the smallest node with the current node as the root node
public int delRightTreeMin(Node node){
Node target = node;
//Binary sort tree can find the left node circularly
while(target.left != null){
target = target.left;
}

//The smallest node is found when you exit the loop
//Delete minimum node
deleteNode(target.value);
return target.value;
}

//Delete node from binary tree
public void deleteNode(int value){
if(this.root == null){
return;
}else{
//Find the node to be deleted
Node targetNode = search(value);
//No node to be deleted found
if(targetNode == null){
return;
}

//The following code defaults to targetnode= null
if(this.root.left == null && this.root.right == null){
//targetNode == root
root = null;
return;
}

//The following code defaults to targetnode= null && targetNode !=  root

//Find the parent node of targetNode
Node parent = searchParent(value);

if(targetNode.left == null && targetNode.right == null){
//The node to be deleted is a leaf node

//Judge the relationship between the current node and the parent node
if(parent.left != null && parent.left.value == value){
//Left child node
parent.left = null;
}else if(parent.right != null && parent.right.value == value){
//Right child node
parent.right = null;
}
}else if(targetNode.left != null && targetNode.right != null){
//There are left and right subtrees for the node to be deleted
int minValue = delRightTreeMin(targetNode.right);
targetNode.value = minValue;
}else{
//The node to be deleted has left subtree or right subtree
if(targetNode.left != null){
//The node to be deleted has a left subtree
if(parent != null){
if(parent.left.value == value){
parent.left = targetNode.left;
}else{
parent.right = targetNode.left;
}
}else{
root = targetNode.left;
}
}else{
//The node to be deleted has a right subtree
if(parent != null){
if(parent.left.value == value){
parent.left = targetNode.right;
}else{
parent.right = targetNode.right;
}
}else{
root = targetNode.right;
}
}
}
}
}

}
public class BinarySortTreeDemo {
public static void main(String[] args) {
int[] array = new int[]{7, 3, 10, 12, 5, 1, 9};

//Create a binary tree object
BinarySortTree bst = new BinarySortTree();
for(Integer temp:array){
}

//Middle order traversal
System.out.println("Middle order traversal:----");
bst.infixOrder();

//Test delete leaf node
bst.deleteNode(1);
bst.deleteNode(5);
bst.deleteNode(10);
bst.deleteNode(12);
bst.deleteNode(3);
bst.deleteNode(9);
bst.deleteNode(7);

System.out.println("After deleting a node:------");
bst.infixOrder();
}
}

```
```Middle order traversal:----
Node{value=1}
Node{value=3}
Node{value=5}
Node{value=7}
Node{value=9}
Node{value=10}
Node{value=12}
After deleting a node:------
Empty tree cannot be traversed
```

# Balanced binary tree

Requirements:
Give you a sequence {1,2,3,4,5,6}, ask to create a binary sort tree (BST), and analyze the problem Analysis of problems in BST

• The left subtree is all empty. From the formal point of view, it is more like a single linked list
• Insertion speed has no effect
• The query speed is significantly reduced (because it needs to be compared in turn), which can not give full play to the advantages of BST

It needs to be solved by using balanced binary (search) tree

Basic introduction:

Balanced binary tree is also called self balancing binary search tree, also known as AVL tree, which can ensure high query efficiency.

It has the following characteristics: it is an empty tree or the absolute value of the height difference between its left and right subtrees does not exceed 1, and both the left and right subtrees are a balanced binary tree. Adding and deleting may require rebalancing the tree through one or more tree rotations

The common implementation methods of balanced binary tree include red black tree, AVL, scapegoat tree, tree, extension tree and so on

## Application case - left rotation

Requirements: give you a sequence of numbers and create the corresponding balanced binary tree Sequence {4,3,6,5,7,8}

Train of thought analysis Note: insert the left subtree of node 6 to the right of node 4, and set node 6 as the root node

```    //Take this as the root node to rotate the binary tree to the left
public void leftRotate(){
//Create a new node attribute, which is the attribute of the root node of the current binary tree
Node newNode = new Node(this.value);
//The left subtree of the new node is set as the left subtree of the current node
newNode.left = this.left;
//The right subtree of the new node is set as the left subtree of the right subtree of the current node
newNode.right = this.right.left;
//Replace the attribute of the current node with the attribute of the right child node
this.value = this.right.value;
//The right subtree of the current node is set as the right subtree of the right subtree of the current node
this.right = this.right.right;
//The left subtree of the current node is set as the new node
this.left = newNode;
}
```

## Application case - right rotation

Requirements: give you a sequence of numbers to create the corresponding balanced binary tree Sequence {10,12,8,9,7,6}

Train of thought analysis: Note: insert the right subtree of node 8 to the left of node 10, and set node 8 as the root node

```//Rotate the binary tree right with this as the root node
public void rightRotate(){
//Create a new node attribute and set it as the attribute of the root node of the current binary tree
Node newNode = new Node(this.value);
//The right subtree of the new node is set as the right subtree of the current node
newNode.right = this.right;
//The left subtree of the new node is set as the right subtree of the left subtree of the current node
newNode.left = this.left.right;
//Replace the attributes of the current node with the attributes of the left child node
this.value = this.left.value;
//The left subtree of the current node is set as the left subtree of the left subtree of the current node
this.left = this.left.left;
//The right subtree of the current node is set as the new node
this.right = newNode;
}
```

## Application case - double rotation

Problem: in some cases, single rotation cannot complete the conversion of balanced binary tree
int[] arr = { 10, 11, 7, 6, 8, 9 }; Running the original code, you can see that it is not converted into AVL tree
int[] arr = {2,1,6,5,7,3}; // Running the original code, you can see that it is not converted into AVL tree resolvent:

Int [] arr = {10, 11, 7, 6, 8, 9} insert node 9

• When the binary tree with this as the root node satisfies the right rotation
• Check: the height of the right subtree of the left subtree of this is greater than the height of the left subtree of the left subtree of this
• First, rotate the left subtree of this
• Then rotate this right

int[] arr = {2,1,6,5,7,3} insert node 3

• When the binary tree with this as the root node satisfies the left rotation
• Check: the height of the left subtree of the right subtree of this is greater than the height of the right subtree of the right subtree of this
• First rotate the right subtree of this
• Then rotate this to the left

Code display:

```package com.atguigu.avl;

import java.util.Arrays;

/**
* @ClassName AVLTreeDemo
* @Author Jeri
* @Date 2022-02-27 10:14
* @Description Construction of balanced binary tree
*/

//Create node class
class Node{
int value;
Node left;
Node right;

public Node(int value) {
this.value = value;
}

//Override toString()
@Override
public String toString() {
return "Node{" +
"value=" + value +
'}';
}

//Middle order traversal
public void infixOrder(){
if(this.left != null){
this.left.infixOrder();
}

System.out.println(this);

if(this.right != null){
this.right.infixOrder();
}
}

public void add(Node node){
//Handling special situations
if(node == null){
return;
}

//Judge node Value and this Value size relationship
if(this.value > node.value){
if(this.left == null){
this.left = node;
}else{
}

}else{
if(this.right == null){
this.right = node;
}else{
}
}

//Balance after adding nodes
if(this.leftHeight() - this.rightHeight() > 1){
//(height of left subtree - height of right subtree) > 1 rotate right
if(this.left != null &&
this.left.rightHeight() > this.left.leftHeight()){
//The height of the right subtree of the left subtree of this > the height of the left subtree of the left subtree of this

//Rotate the left subtree of this
this.left.leftRotate();

//this makes a right rotation
this.rightRotate();
}else{
//this makes a right rotation
this.rightRotate();
}

return;
}

if(this.rightHeight() - this.leftHeight() > 1){
//(height of right subtree - height of left subtree) > 1 rotate left
if(this.right != null &&
this.right.leftHeight() > this.right.rightHeight()){
//The height of the left subtree of the right subtree of this > the height of the right subtree of the right subtree of this

//Right rotation of the right subtree of this
this.right.rightRotate();

//Rotate this left
this.leftRotate();
}else{
//Rotate this left
this.leftRotate();
}

return;
}
}

//Returns the height of the tree with this as the root node
public int height(){
return Math.max(this.left == null?0:this.left.height(),
this.right == null?0:this.right.height()) + 1;
}

//Returns the height of the left subtree with this as the root node
public int leftHeight(){
if(this.left == null){
return 0;
}
return this.left.height();
}

//Returns the height of the right subtree with this as the root node
public int rightHeight(){
if(this.right == null){
return 0;
}
return this.right.height();
}

//Take this as the root node to rotate the binary tree to the left
public void leftRotate(){
//Create a new node attribute, which is the attribute of the root node of the current binary tree
Node newNode = new Node(this.value);
//The left subtree of the new node is set as the left subtree of the current node
newNode.left = this.left;
//The right subtree of the new node is set as the left subtree of the right subtree of the current node
newNode.right = this.right.left;
//Replace the attribute of the current node with the attribute of the right child node
this.value = this.right.value;
//The right subtree of the current node is set as the right subtree of the right subtree of the current node
this.right = this.right.right;
//The left subtree of the current node is set as the new node
this.left = newNode;

}

//Rotate the binary tree right with this as the root node
public void rightRotate(){
//Create a new node attribute and set it as the attribute of the root node of the current binary tree
Node newNode = new Node(this.value);
//The right subtree of the new node is set as the right subtree of the current node
newNode.right = this.right;
//The left subtree of the new node is set as the right subtree of the left subtree of the current node
newNode.left = this.left.right;
//Replace the attributes of the current node with the attributes of the left child node
this.value = this.left.value;
//The left subtree of the current node is set as the left subtree of the left subtree of the current node
this.left = this.left.left;
//The right subtree of the current node is set as the new node
this.right = newNode;
}

}

//Create balance tree
class AVLTree{
private Node root;

public Node getRoot() {
return root;
}

public void setRoot(Node root) {
this.root = root;
}

//Add node to balance tree
public void add(Node node){
if(this.root == null){
this.root = node;
}else{
}
}

//Order traversal in balanced tree
public void infixOrder(){
if(this.root == null){
System.out.println("Empty tree cannot be traversed");
}else{
this.root.infixOrder();
}
}
}
public class AVLTreeDemo {
public static void main(String[] args) {
//int[] arr = {4,3,6,5,7,8};
//int[] arr = {2,1,6,5,7,3};
int[] arr = { 10, 11, 7, 6, 8, 9 };

System.out.println("Original array:-----");
System.out.println(Arrays.toString(arr));
//Create an AVLTree object
AVLTree avlTree = new AVLTree();

for(int i=0; i < arr.length; i++) {
}

//ergodic
System.out.println("Middle order traversal");
avlTree.infixOrder();

System.out.println("In balance processing~~");
System.out.println("Current root node=" + avlTree.getRoot());
System.out.println("Height of tree=" + avlTree.getRoot().height());
System.out.println("Height of the left subtree of the tree=" + avlTree.getRoot().leftHeight());
System.out.println("Height of right subtree of tree=" + avlTree.getRoot().rightHeight());

}
}
```
```Original array:-----
[10, 11, 7, 6, 8, 9]
Middle order traversal
Node{value=6}
Node{value=7}
Node{value=8}
Node{value=9}
Node{value=10}
Node{value=11}
In balance processing~~
Current root node=Node{value=8}
Height of tree=3
Height of the left subtree of the tree=2
Height of right subtree of tree=2
```
```Original array:-----
[2, 1, 6, 5, 7, 3]
Middle order traversal
Node{value=1}
Node{value=2}
Node{value=3}
Node{value=5}
Node{value=6}
Node{value=7}
In balance processing~~
Current root node=Node{value=5}
Height of tree=3
Height of the left subtree of the tree=2
Height of right subtree of tree=2
```

# reference

Java data structure and Java algorithm

Keywords: Algorithm data structure

Added by jefffan24 on Sun, 27 Feb 2022 05:43:02 +0200