Binary search tree learning

Binary search tree: For a binary search tree, if the child is not left empty, the father left the child node is greater than the value; if the right child is not empty, then the right child's value is greater than the value of the parent node.
The same as the following chart:
Here Insert Picture Description


二叉搜索树的创建和插入
This article summarizes the principal created and inserted into the binary search tree, deleted, feeling futile, do not want to write.

创建
Create it, and create the difference between a binary tree on the so Diudiu, but have to add a judge, according to the nature, the father left the child node value is less than the right child node value than the big father, so add a judge.

Determine whether the root node is empty, not empty words, when the node is added is larger than the current node, then create a node to the right; otherwise add nodes to the left; is empty, then the node will directly create new data are stored.

  //添加新元素
    shared_ptr<node> build(shared_ptr<node>root, int e)
    {
        if(root == NULL)
        {
            size ++ ;
             shared_ptr<node>p = make_shared<node>(e) ;
             return p ;
        }
        else
        {
            if(e > root->a)
            {
                root->r = build(root->r, e) ;
            }
            else
            {
                root->l = build(root->l, e) ;
            }
        }
        return root ;
    }

插入
Insertion operation, then there are two ways:

  • NO.1
    incoming data

判断要是比当前节点大的话Which was inserted into the right subtree of the current node, the value of the size of course, do not forget the right child node is inserted into the comparison data and the right child node is larger than the data inserted in the data, as a right child to the right child of the inserted data, as insert data left child.

Otherwise, the data is inserted into the left sub-tree, the same node and the current node is inserted into the right child to compare the data and decided to left child of the current node as data is inserted left child or right child.

In short, we must follow the principle of the beginning of the article, in order to safeguard the binary search tree.
: As shown in Figure
Here Insert Picture Descriptionso inserted advantage is quick and easy.

  • NO.2
    I think we should all find a practice on the insertion time complexity is O (1), with the increase of data, it is likely to make our binary search tree degenerates into a linked list, then we Qibushibai busy !
    A plug for the method, I was rejected! ! !
    So I insert this method is the following:

Continue scratch start node, the node compares the current value of the data and the data is inserted,
is larger than the data words inserted:

  • Determining whether the right subtree of the current node is empty, empty it, to be inserted directly into a node found right subtree of the current node position.
  • If not empty
    • Comparative interpolation value and the right subtree node data, but also if the data is greater than or equal right subtree, then it is directly to the right sub-tree recursively.
    • If less than the right sub-tree nodes, the inserted data and the current data exchange node, left recursive comparison.

If the current node is smaller than the insertion of data, it is similar to the right to the left.

I think this is inserted into the time complexity is o (logn), but he always maintains this binary search tree will not degenerate into a linked list.

The following is a process diagram:
Here Insert Picture Description
The above is part of the process diagram, and if it can not read the test code and the following is implemented, may help understand this process, the traversal is preorder traversal of a binary tree.

#include <iostream>
#include<memory>
using namespace std ;
//二叉搜索树的学习

class node
{
    
    public :
        shared_ptr<node>l ;
        shared_ptr<node>r ;
        int a ;
    public :
        node()
        {
            a = 0 ;
            l = NULL ;
            r = NULL ;
        }

        node(int e)
        {
            a = e ;
            l = NULL ;
            r = NULL ;
        }

        ~node()
        {
            l = NULL ;
            r = NULL ;
        }
};

class BST: public node 
{
private :
    shared_ptr<node>root ;
    int size ;
    int a ;
public : 
    BST()
    {
        node() ;
        root = NULL ;
        size = 0 ;
    }
    
    ~BST()
    {
    }

public :
    void build()
    {
        int e ;
        while(1)
        {
            cin >>e ;
            if(e != -1)
            {
                root = build(root, e) ;
            }
            else 
            {
                break ;
            }
        }
    }

    //添加新元素
    shared_ptr<node> build(shared_ptr<node>root, int e)
    {
        if(root == NULL)
        {
            size ++ ;

             shared_ptr<node>p = make_shared<node>(e) ;
            
             return p ;
        }

        else
        {
            if(e > root->a)
            {
                root->r = build(root->r, e) ;
            }

            else 
            {
                root->l = build(root->l, e) ;
            }
        }

        return root ;
    }       

    void print()
    {
        print(root) ;
    }

    void print(shared_ptr<node>root)
    {
           if(root)
           {        
                cout << root->a <<endl ;
                print(root->l) ;
                print(root->r) ;
           }
    }
    
    //向树中插入元素
    void add(int e)
    {
        root = add(root, e) ;
        cout << "插入元素"<<e<<"后:" << endl ;
        print(root) ;
    }

    shared_ptr<node> add(shared_ptr<node>root, int e)
    {
        if(root == NULL)
        {
            return shared_ptr<node>(new node(e)) ;
        }
        else
        {
            if(e < root->a)
            {
              
                if(root->l == NULL)
                {
                    root->l = add(root->l, e) ;
                }

                //要是e不小于当前节点的左孩子数据
                if(e > root->l->a)
                {
                    swap(root->a, e) ;
                    add(root->r , e) ;
                } 

                if(e <= root->l->a)
                {
                    add(root->l, e) ;
                }
            }

            else if(e > root->a)
            {   
                if(root->r == NULL)
                {
                    root->r = add(root->r, e) ;
                }

                if(root->r->a > e)
                {
                    swap(root->a, e) ;
                    add(root->l, e) ;
                }

                if(root->r->a <= e)
                {
                    add(root->r, e) ;
                }
            }

            else
            {
                add(root->r, e) ;
            }
        }

        return root ;
    }

    void swap(int& old_, int& new_)
    {
        int temp = old_ ;
        old_ = new_ ;
        new_ = temp ;
    }

    //删除元素,感觉不常用,所以偷懒不写了!!!
    //思路:
    //1.当有左右孩子时
    //将左子树的最大节点或者右子树的最小节点调到当前节点位置即可这里省略了....
    //2.当没有左右孩子时,将当前节点指向空
    //3.当仅有右孩子或者左孩子,将当前节点的父亲节点指向该节点的左子树或者右子树即可
};

int main()
{
    BST bst ;
    //创建搜索树
    bst.build() ;
    bst.print() ;
	//插入40
    bst.add(40) ;
}

测试数据及结果

51 23 58 15 25 60 57 12 19 27 30 -1
51   23   15   12   19   25   27   30   58   57   60   
插入元素40后:
40   23   15   12   19   25   27   30   58   57   51   60   

Guess you like

Origin blog.csdn.net/qq_41681241/article/details/88796935