Write a binary search tree (BST) by hand

foreword

I wrote a simple two-way linked list in the last article. The difficulty is 简简单单that this time I will try a binary tree. The difficulty is that 也还行吧it is somewhat exaggerated, but for the big guys, these are simple.

Difficulty list:

  • Collection : as long as you have it
  • Linked list : simple and simple
  • Queues : basic operations
  • Binary tree : okay
  • Balanced binary tree : mediocre
  • Red-black tree : a bit difficult
  • Heap/Stack : Increased Difficulty
  • Picture : Today is the high-end bureau

Attributes

A binary tree has a root node, and most operations are processed downward based on the root node, so a root node root needs to be explicitly defined.

private Node root;

Each node of the binary tree has left and right nodes and its own attribute values, so Nodethe content needs to have the attribute sum of the left leftand right nodes right, as for its own attributes Demo, use the numeric typeInteger

code show as below:

    private class Node{
    
    
        private Node left;
        private Node right;
        private Integer data;
        
        public Node(Integer data){
    
    
            this.data = data;
        }
        
    }

ADD

Step 1 : Determine rootwhether it is empty, initialize the node if it is empty root, otherwise execute addthe method

    private void add(int data) {
    
    
        if (Objects.isNull(root)){
    
    
            root = new Node(data);
        }else{
    
    
            root.add(data);
        }
    }

Step 2 : add method, judge whether the parameter value is smaller than the node value, if it is smaller, move to the left node for processing, and if it is larger, move to the right node for processing

        private void add(Integer data) {
    
    
            if (this.data >= data){
    
    
                // left
            }else{
    
    
                // right
            }
        }

Step 3 : Determine 左/右whether the node is empty, initialize the node if it is empty, otherwise proceed addrecursively

        private void add(Integer data) {
    
    
            if (this.data >= data){
    
    
                if (Objects.isNull(this.left)){
    
    
                    this.left = new Node(data);
                }else{
    
    
                    this.left.add(data);
                }
            }else{
    
    
                if (Objects.isNull(this.right)){
    
    
                    this.right = new Node(data);
                }else{
    
    
                    this.right.add(data);
                }
            }
        }

GET

There are three ways to traverse the query value of the binary search tree:

  • preorder traversal
  • Inorder traversal
  • Subsequent traversal

Not all of them are included here, so we choose the most commonly used 中序遍历one as the traversal method for our query value content

code show as below:

        public Node get(Integer data) {
    
    
            Node now = this;
            if (now.data == data){
    
    
                return now;
            }else{
    
    
                if (now.left != null){
    
    
                    Node left = now.left.get(data);
                    if (left != null){
    
    
                        return left;
                    }
                }
                if (now.right != null){
    
    
                    Node right = now.right.get(data);
                    if (right != null){
    
    
                        return right;
                    }
                }
            }
            return null;
        }

Delete

The deletion operation is the most complicated in the binary search tree. It can be adjusted according to the different needs of the deleted node. The classification has the following categories:

  • Leaf node : A leaf node is a node that has neither left nor right node attributes, which can be deleted directly
  • One-way non-leaf node : One-way non-leaf node means that only one node exists in the left and right nodes, and this kind of 删除节点pointer 子节点can be directly pointed to
  • Bidirectional non-leaf node : If both the left and right nodes of the deleted node exist, this is true 最复杂, because if you delete this kind of node, you need to move the child nodes,
    find the rightmost node of the left node to replace the position of the deleted node, the previous node Location deleted.

Delete code:

        public Node delete(Node parrent, Integer data) {
    
    
            if (this != null){
    
    
                if (this.data == data){
    
    
                    if (this.left == null && this.right == null){
    
    
                        if (parrent.left != null && parrent.left.data == data){
    
    
                            parrent.left = null;
                        }else {
    
    
                            parrent.right = null;
                        }
                    }else if(this.left != null && this.right == null){
    
    
                        parrent.left = this.left;
                    }else if(this.left == null && this.right != null){
    
    
                        parrent.right = this.right;
                    }else{
    
    
                        Node node = this.left.getRightNode(this.left);
                        node.left = this.left;
                        node.right = this.right;
                        if (parrent.left != null && parrent.left.data == data){
    
    
                            parrent.left = node;
                        }else {
    
    
                            parrent.right = node;
                        }
                    }
                }else{
    
    
                    if (data > this.data) {
    
    
                        this.right.delete(this,data);
                    } else {
    
    
                        this.left.delete(this,data);
                    }
                    return this;
                }
            }
            return null;
        }

Get the leftmost leaf node and delete and return

I wrote two ways to get the leftmost node, one is recursive and the other is circular

Recursive way:

        private Node getRightNode(Node node){
    
    
            if(this.right != null){
    
    
            	return this.right.getRightNode(this);
            }
            node.right = null;
            return this;
        }

Cycle mode:

        private Node getRightNode(Node node){
    
    
            Node now = this;
            Node buffer = this;
            while(now.right != null){
    
    
                buffer = now;
                now = now.right;
            }
            buffer.right = null;
            return now;
        }

verify

Write some data into the tree structure and delete the nodes in it, and check whether the output content is corresponding.

code show as below:

    public static void main(String[] args) {
    
    
        OrdinaryBinaryTree tree = new OrdinaryBinaryTree();
        tree.add(4);tree.add(7);tree.add(8);tree.add(2);
        tree.add(-1);tree.add(3);tree.add(0);tree.add(11);tree.add(14);tree.add(21);tree.add(9);
        tree.print();
        tree.delete(2);
        tree.print();
    }

result:

insert image description here

Graphical Structure: Raw Data

delete money

Graphical Structure: Deleted Structure

insert image description here

Guess you like

Origin blog.csdn.net/AnNanDu/article/details/126626561