Binary search tree (java implementation)

Contents
  1. Insert element idea and implementation
  2. Delete element idea and implementation
  3. Complete code

Definition of binary search tree

A binary search tree, also known as an ordered binary tree, or an ordered binary tree, refers to an empty tree or a binary tree with the following properties:

  1. If the left subtree of any node is not empty, the value of all nodes on the left subtree is less than the value of its root node;

  2. If the right subtree of any node is not empty, the value of all nodes on the right subtree is greater than the value of its root node;

  3. The left and right subtrees of any node are also binary search trees, respectively.

  4. There are no nodes with equal keys.

Construct the node:

class Node<T extends Comparable> {
    int key;
    T val;
    Node<T> left;
    Node<T> right;

    public Node() {

    }

    public Node(int key, T val) {
        this.key = key;
        this.val = val;
    }
}

binary search tree insertion

  The process of insertion is : compare the current node, if it is smaller than the current node, look up the left subtree. If it is greater than the current node, search to the right subtree. Until the searched subtree is an empty tree, it is the insertion position.

private void insertKV(int key, T val) {
        // 如果是空树,则插入的节点为根节点
     if (root == null) {
        root = new Node<T>(key, val);
        return;
     }
     Node cur = root;
     Node parent = root;
     boolean isLeftNode = true;
     while (cur != null) {//直到找到该插入的位置
        parent = cur;
        if (key < cur.key) { // 如果小于当前节点的值,往左子树查找
           cur = cur.left;
           isLeftNode = true;
        } else { // 如果大于当前节点的值,往右子树查找
           cur = cur.right;
           isLeftNode = false;
        }
     }
     Node newNode = new Node(key, val);
     if (isLeftNode) {
         parent.left = newNode;
     } else {
         parent.right = newNode;
   }
}

Deletion of a binary search tree

Deletion is probably the most complicated case in a binary search tree.

There are 4 situations:

  • The deleted element is a leaf
      node , and the reference of the parent node of the node to the node can be pointed to null
  • Delete element only has the right child Move the right child of
      the node up one level
  • Delete element only has left child Move the left child of
      the node up one level
  • The deleted element has both left and right children (this is the most complicated case) and
      needs to be rotated up and down while maintaining the structure of the sorted tree

1.1 First locate the current node to the node to be deleted

 /**
 * 找到要删除的节点,并把当前结点定位到要删除的节点
*/
while (cur.key!=key){
    parent = cur;
    if(key<cur.key){ //如果删除的元素在左子树
        isLeftChild = true;//在左子树设为true
        cur = cur.left;
    }else { //如果删除的元素在右子树
        isLeftChild = false;
        cur = cur.right;
    }
    if(cur == null){//不存在该节点
        return false;
    }
}

1.2.1 Delete leaf nodes

if(cur.left == null&&cur.right==null){//当前结点是叶子节点的时候
    if(cur == root){ //是根节点,且根节点没有叶子节点的时候
        root = null; // 树为空树
    }
    else if(isLeftChild){// 当前结点是左孩子节点
        parent.left = null; //父节点的左孩子设为空
    }else {// 当前结点是右孩子节点
        parent.right = null;//父节点的左孩子设为空
    }
}

1.2.2 delete element only right child

else if(cur.left == null){//当前结点没有左孩子,只有右孩子
    if (cur == root){ //当前结点为根
        root = cur.right;//左子树上移
    }else if(isLeftChild){ // 当前结点是其父节点的左孩子
        parent.left = cur.right;
    }else { // 当前结点是其父节点的右孩子
        parent.right = cur.right;
    }
}

1.2.3 delete element only left child

else if(cur.right == null){//当前结点没有右孩子,只有左孩子
    if (cur == root){ //当前结点为根
        root = cur.left;//左子树上移
    }else if(isLeftChild){ // 当前结点是其父节点的左孩子
        parent.left = cur.left;
    }else { // 当前结点是其父节点的右孩子
        parent.right = cur.left;
    }
}

1.2.4 Deleted elements have both left and right children

else {//当前结点有左孩子,也有右孩子
    Node<T> successor = getSuccessor(cur);
    if(cur == root){
        root = successor;
    }
    else if(isLeftChild){
        parent.left = successor;
    }
    else {
        parent.right = successor;
    }
    //将删除节点的左子树接到旋好的树的左子树上
    successor.left = cur.left;
}

/**
* 将要删除节点为根节点的树
* 进行旋转操作
* @param delNode 要删除的节点
* @return 旋好的子树
*/
private Node<T> getSuccessor(Node delNode) {
    Node<T> successorParent = delNode;
    Node<T> successor = delNode;
    Node<T> cur = delNode.right;
    while(cur!=null){
        successorParent = successor;
        successor = cur;
        cur = cur.left;
    }
    if(successor!=delNode.right){
        successorParent.left = successor.right;
        successor.right = delNode.right;
    }
    return successor;
}

Delete 18 nodes, the code execution process. After the rotation result, the tree rooted at 18 becomes the right image. The dotted line is the left subtree connected to 18 after the rotation.

write picture description here

The same is to delete 18 nodes, the subtree of 18 becomes more complicated, and the converted subtree is as right

write picture description here

write picture description here

write picture description here

After looking at these rotated pictures, you can know my idea of ​​rotating the subtree.

First, look at the right subtree of the deleted node. If it is empty, move the right child node of the node up one level.

If the right subtree is not empty, look at the left subtree of the right subtree. If the left subtree is empty, move the entire right subtree up one level.

If the left subtree of the right subtree is not empty and the left subtree has no child nodes, directly refer the left subtree of the right subtree to the position where the node is to be deleted

When there is a left child, a loop like the above works, until the left child is empty, the loop stops.

The above is my personal understanding of the implementation. You can roughly compare these pictures to achieve the purpose of understanding.
Note: The rotation implementation can be defined as long as the characteristics of the binary search tree can be guaranteed. Rotation isn't just one implementation either.

full code

Full code address: my code

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325766273&siteId=291194637