zoukankan      html  css  js  c++  java
  • 二叉排序树

    二叉排序树

    什么是二叉排序树、

    二叉排序树要么是空二叉树,要么具有如下性质:

    二叉排序树中,如果其根结点有左子树,那么左子树上所有结点的值都小于根结点的值;
    二叉排序树中,如果其根结点有右子树,那么右子树上所有结点的值都大于根结点的值;
    二叉排序树的左右子树也要求都是二叉排序树.

    例子

    image
    根据以上性质,我们得知二叉排序树的中序遍历是一个有序序列(升序),如上图中序遍历得到的序列为:1 2 10 14 18 20 22

    结构定义

    struct Node {
        int key;
        Node *lchild, *rchild;
    };
    

    节点初始化

    我们定义一个函数Node* getNewNode(int key),其传入参数是一个key,返回值为一个节点地址,表示初始化一个具体key值的节点,这里是为了给插入节点函数服务所实现的。

    Node *getNewNode(int key) {
        Node *p = (Node *)malloc(sizeof(Node));
        p->key = key;
        p->lchild = p->rchild = NIL;
    }
    

    插入操作

    根据上面二叉排序树的性质1和性质2,当我们往一个二叉排序树种插入一个节点时,当要插入的节点的key值小于根节点的key值,则递归插入到根节点的左子树;若要插入的节点的key值大于根节点的key值,则递归插入到根节点的右子树;若二叉排序树中存在与要插入节点一样key值得节点,则不插入并返回该节点的地址。由于性质决定,插入的新节点,一定会是二叉排序树的叶子节点。

    代码

    Node *insert(Node *root, int key) {
        //root是空,则表明从根节点遍历到这个空节点都没有找到与参数key值一样的节点,可以在这里插入新节点,且插入后该节点为叶子节点
        if (root == NULL) {
            return getNewNode(key);
        }
        if (key == root->key) {//这里不重复插入相同key值得节点
            return root;
        }
        if (key < root->key) {//若插入key比当前节点的key小,则递归到当前节点的左子树中去插入
            root->lchild = insert(root->lchild, key);
        } else (key > root->key) {//若插入key比当前节点的key大,则递归到当前节点的右子树中去插入
            root->rchild = insert(root->rchild, key);
        }
        return root;
    }
    

    删除操作

    根据删除节点的度来区分,我们可以把删除操作主要分为三个部分,:

    删除度为0的节点 -> 直接删除
    删除度为1的节点 -> 把删除节点的孤儿节点挂到自己的位置上
    删除度为2的节点 -> 转化为删除要删除节点的前驱或者后继

    对于度为2的节点:
    前驱 -> 左子树的最大值
    后继 -> 右子树的最小值
    删除度为2的例子
    比如我们想删除节点23,节点23度为2,这时候我们找到它的前驱节点19,把前驱节点的key值填到23节点的位置,再删除23的前驱节点19。
    image

    代码

    求出某个节点前驱的代码

    //传入某个节点的地址root,然后求出root节点的前驱节点的地址,并返回
    Node *prodecessor(Node *root) {
        Node *p = root->lchild;
        while (p != NIL) {
            p = p->rchild;
        }
        return p;
    }
    

    删除节点代码

    Node *erase(Node *root, int key) {
        //root是空,则表明从根节点遍历到这个空节点都没有找到与参数key值一样的节点,直接返回
        if (root == NULL) {
            return root;
        }
        if (key < root->key) {//key值小于当前节点的key,则要删除的点在root的左子树上
            root->lchild = erase(root->lchild, key);
        } else if (key > root->key) {//key值大于当前节点的key,则要删除的点在root的左子树上
            root->rchild = erase(root->rchild, key);
        } else {//key值与当前节点的key一样,则以度的数量开始区分删除情况。
            if (root->lchild == NULL && root->rchild == NULL) {//度为1:直接删除
                free(root);;
                return NULL;
            } else if (root->lchild == NULL || root->rchild == NULL) {//度为2:直接返回孤儿节点的地址给自身
                Node *temp = root->lchild == NULL ? root->rchild : root->lchild;
                free(root);
                return temp;
            } else {//度为2:直接转化为删除该节点的前驱节点
                Node *temp = predecessor(root);
                root->key = temp->key;
                root->lchild = erase(root->lchild, temp->key);
            }
        }
        return root;
    }
    

    遍历二叉排序树

    这里我们采用中序遍历的方式遍历二叉排序树。

    void in_order(Node *root) {
        if (root == NULL) {
            return ;
        }
        in_order(root->lchild);
        printf("%d ", root->key);
        in_order(root->rchild);
        return ;
    }
    

    完整代码

    这里我们给出完整代码,该代码带有测试程序,首先根据提示,有选择操作的选项,输入1表示插入操作;输入2表示删除操作,选择完操作后,需要输入一个key,然后每次操作完毕,都会中序遍历输出该二叉排序树的所有节点。

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    #define KEY(n) (n ? n->key : -1)
    
    typedef struct Node {
        int key;
        struct Node *lchild, *rchild;
    } Node;
    
    Node *getNewNode(int key) {
        Node *p = (Node *)malloc(sizeof(Node));
        p->key = key;
        p->lchild = p->rchild = NULL;
    }
    
    void clear(Node *root) {
        if (root == NULL) {
            return ;
        }
        clear(root->lchild);
        clear(root->rchild);
        free(root);
        return ;
    }
    
    Node *insert(Node *root, int key) {
        //root是空,则表明从根节点遍历到这个空节点都没有找到与参数key值一样的节点,可以在这里插入新节点,且插入后该节点为叶子节点
        if (root == NULL) {
            return getNewNode(key);
        }
        if (root->key == key) {//这里不重复插入相同key值得节点
            return root;
        }
        if (key < root->key) {//若插入key比当前节点的key小,则递归到当前节点的左子树中去插入
            root->lchild = insert(root->lchild, key);
        } else {//若插入key比当前节点的key大,则递归到当前节点的右子树中去插入
            root->rchild = insert(root->rchild, key);
        }
        return root;
    }
    
    
    Node *prodecessor(Node *root) {
        Node *p = root->lchild;
        while (p->rchild != NULL) {
            p = p->rchild;
        }
        return p;
    }
    
    Node *erase(Node *root, int key) {
        //root是空,则表明从根节点遍历到这个空节点都没有找到与参数key值一样的节点,直接返回
        if (root == NULL) {
            return root;
        }
        if (key < root->key) {//key值小于当前节点的key,则要删除的点在root的左子树上
            root->lchild = erase(root->lchild, key);
        } else if (key > root->key){//key值大于当前节点的key,则要删除的点在root的左子树上
            root->rchild = erase(root->rchild, key);
        } else {//key值与当前节点的key一样,则以度的数量开始区分删除情况。
            if (root->lchild == NULL && root->rchild == NULL) {//度为0:直接删除
                free(root);
                return NULL;
            } else if (root->lchild == NULL || root->rchild == NULL) {//度为1:直接返回孤儿节点的地址给自身
                Node *p = root->lchild == NULL ? root->rchild : root->lchild;
                free(root);
                return p;
            } else {//度为2:直接转化为删除该节点的前驱节点
                Node *p = prodecessor(root);
                root->key = p->key;
                root->lchild = erase(root->lchild, p->key);
            }
        }
        return root;
    }
    
    void print_node(Node *root) {
        printf("(%d: %d, %d)
    ", KEY(root), KEY(root->lchild), KEY(root->rchild));
    }
    
    void _in_order(Node *root) {
        if (root == NULL) {
            return ;
        }
        _in_order(root->lchild);
        print_node(root);
        _in_order(root->rchild);
        return ;
    }
    
    void in_order(Node *root) {
        printf("binary tree:
    ");
        _in_order(root);
        printf("
    
    ");
    }
    
    void menu(void) {
        printf("Please enter the operation: 
    ");
        printf("Press 1 to insert a node to binary search tree
    ");
        printf("Press 2 to delete a node from binary search tree
    ");
        printf("Press TRL + D to quit!
    ");
    }
    
    int main() {
        Node *root = NULL;
        int op, key;
        menu();
        while (~scanf("%d", &op)) {
            if (op != 1 && op != 2) {
                printf("please enter the right operation!
    ");
                continue;
            }
            switch (op) {
                case 1:
                    printf("Enter the key you want to insert: ");
                    scanf("%d", &key);
                    root = insert(root, key);
                break;
    
                case 2:
                    printf("Enter the key you want to delete: ");
                    scanf("%d", &key);
                    root = erase(root, key);
                break;
            }
            in_order(root);
            menu();
        }
        clear(root);
        return 0;
    }
    

    测试结果

    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press TRL + D to quit!
    1
    Enter the key you want to insert: 12
    binary tree:
    (12: -1, -1)
    
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press TRL + D to quit!
    1
    Enter the key you want to insert: 8
    binary tree:
    (8: -1, -1)
    (12: 8, -1)
    
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press TRL + D to quit!
    1
    Enter the key you want to insert: 34
    binary tree:
    (8: -1, -1)
    (12: 8, 34)
    (34: -1, -1)
    
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press TRL + D to quit!
    1
    Enter the key you want to insert: 56
    binary tree:
    (8: -1, -1)
    (12: 8, 34)
    (34: -1, 56)
    (56: -1, -1)
    
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press TRL + D to quit!
    2 12
    Enter the key you want to delete: binary tree:
    (8: -1, 34)
    (34: -1, 56)
    (56: -1, -1)
    
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press TRL + D to quit!
    1 12
    Enter the key you want to insert: binary tree:
    (8: -1, 34)
    (12: -1, -1)
    (34: 12, 56)
    (56: -1, -1)
    
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press TRL + D to quit!
    

    思考

    如果我们分别进行两棵二叉排序树的插入构建。其中插入到这两棵树的节点的key和节点数量完全相同,唯一不同的是插入顺序不同,例如:
    第一棵树按一下顺序插入6个元素: 6 9 3 2 7 5
    第二棵树按以下顺序插入6个元素: 2 3 5 6 7 9
    查找一个元素的时间复杂度一样吗?
    这里,我们先直接画出这两棵树
    第一棵
    image
    第二棵
    image
    这里的时候,第一棵二叉排序树的元素平均查找期望是(1+2*2+3*3)/6 = 5/2,大致是O(logN)级别的时间复杂度;而第二棵树的凭据查找期望是(1+2+3+4+5+6)/6 = 7/3,且这很明显,这里第二颗树已经退化成链表,这时候它的查找效率是O(N),而对比第一棵树,由于是一棵完全二叉树,其查找效率在O(logN)。由此,我们可以下定结论:

    1. 插入顺序会影响最终的树形结构
    2. 不同的树形结构,查找效率不同

    为了解决以上二叉排序树会退化成链表,导致查找效率变低的情况,在二叉排序树的基础上,二叉平衡树诞生了。

    拓展

    二叉排序树的删除代码优化

    删除掉处理度为0的代码逻辑,不影响代码整体功能

    Node *erase(Node *root, int key) {
        //root是空,则表明从根节点遍历到这个空节点都没有找到与参数key值一样的节点,直接返回
        if (root == NULL) {
            return root;
        }
        if (key < root->key) {//key值小于当前节点的key,则要删除的点在root的左子树上
            root->lchild = erase(root->lchild, key);
        } else if (key > root->key) {//key值大于当前节点的key,则要删除的点在root的左子树上
            root->rchild = erase(root->rchild, key);
        } else {//key值与当前节点的key一样,则以度的数量开始区分删除情况。
            if (root->lchild == NULL || root->rchild == NULL) {//删除度为0或者1都可以这个分支。
                Node *temp = root->lchild == NULL ? root->rchild : root->lchild;
                delete root;
                return temp;
            } else {//度为2:直接转化为删除该节点的前驱节点
                Node *temp = predecessor(root);
                root->key = temp->key;
                root->lchild = erase(root->lchild, temp->key);
            }
        }
        return root;
    }
    

    如何解决排名相关的检索需求

    1. 修改二叉排序树的结构定义,增加 size 字段,记录每棵树的节点数量
    2. 若K = LS + 1,则根节点就是排名第 k 位的元素
    3. 若K <= LS,则排名第 K 位的元素在左子树中
    4. 若K > LS + 1,则排名第 k 位的元素在右子树中
      PS:LS指某个节点的左子树节点数量

    带排名版本的二叉排序树

    结构定义
    typedef struct Node {
        int key, size;
        struct Node *lchild, *rchild;
    } Node;
    

    在结构定义中,增加了size字段名,用来记录每个子树的节点数量。

    节点初始化
    Node *getNewNode(int key) {
        Node *p = (Node *)malloc(sizeof(Node));
        p->key = key;
        p->size = 1;
        p->lchild = p->rchild = NULL;
    }
    

    节点初始化,由于增加了size字段,同样的,节点初始化的时候,size字段也要初始化为1.

    子树节点数量更新函数
    void update_size(Node *root) {
        root->size = SIZE(root->lchild) + SIZE(root->rchild) + 1;
    }
    

    每一个根节点的节点数量为其左右子树节点数的和加1。

    插入
    Node *insert(Node *root, int key) {
        //root是空,则表明从根节点遍历到这个空节点都没有找到与参数key值一样的节点,可以在这里插入新节点,且插入后该节点为叶子节点
        if (root == NULL) {
            return getNewNode(key);
        }
        if (root->key == key) {//这里不重复插入相同key值得节点
            return root;
        }
        if (key < root->key) {//若插入key比当前节点的key小,则递归到当前节点的左子树中去插入
            root->lchild = insert(root->lchild, key);
        } else {//若插入key比当前节点的key大,则递归到当前节点的右子树中去插入
            root->rchild = insert(root->rchild, key);
        }
        update_size(root);//更新节点数量
        return root;
    }
    

    在插入操作返回前,必须先更新节点数量。

    删除
    Node *erase(Node *root, int key) {
        //root是空,则表明从根节点遍历到这个空节点都没有找到与参数key值一样的节点,直接返回
        if (root == NULL) {
            return root;
        }
        if (key < root->key) {//key值小于当前节点的key,则要删除的点在root的左子树上
            root->lchild = erase(root->lchild, key);
        } else if (key > root->key){//key值大于当前节点的key,则要删除的点在root的左子树上
            root->rchild = erase(root->rchild, key);
        } else {//key值与当前节点的key一样,则以度的数量开始区分删除情况。
            if (root->lchild == NULL || root->rchild == NULL) {//删除度为0或者1都可以这个分支。
                Node *p = root->lchild == NULL ? root->rchild : root->lchild;
                free(root);
                return p;
            } else {////度为2:直接转化为删除该节点的前驱节点
                Node *p = prodecessor(root);
                root->key = p->key;
                root->lchild = erase(root->lchild, p->key);
            }
        }
        update_size(root);//更新节点数量
        return root;
    }
    

    同样的,在删除操作返回前,也要更新节点数量。

    注意

    无论是插入还是删除,之所以在返回root节点前更新节点数量,这是因为插入和删除只会影响到回溯时经过的节点(也就是插入节点的祖先节点)对应的子树的节点数量。

    查找第K位元素
    int find_k(Node *root, int k) {
        if (root == NULL || k == 0) {
            return -1;
        }
        if (k == SIZE(root->lchild) + 1) {//若root节点的左子树节点数量 + 1等于 k,则root节点就是第K个节点
            return root->key;
        }
        if (k <= SIZE(root->lchild)) {//若root节点的左子树节点数量大于等于k,则递归到左子树中去找第K个节点
            return find_k(root->lchild, k);
        }
        //若root左子树节点数量 + 1小于K,则递归到右子树中去找右子树中第K - size(L(root)) - 1个节点。
        if (k > SIZE(root->lchild) + 1) {
            return find_k(root->rchild, k - SIZE(root->lchild) - 1);
        }
    }
    
    宏定义
    #define KEY(n) (n ? n->key : -1)//返回某个节点的key值
    #define SIZE(n) (n ? n->size : 0)//返回某个节点对应的树的节点数量
    

    解决 Top-K 问题(找到小于第 k 位的所有元素)

    1. 根节点就是第 k 位元素的话,就把左子树中的值全部输出出来
    2. 第 k 位在左子树中,前 k 位元素全都在左子树中
    3. 第 k 位在右子树中,说明根节点和左子树中的元素,都是前 k 位元素里面的值
    void output_k(Node *root, int k) {
        if (root == NULL || k <= 0) {
            return ;
        }
        if (k == SIZE(root->lchild)) {
            _in_order(root->lchild);
        } else if (k < SIZE(root->lchild)) {
            output_k(root->lchild, k);
        } else {
            _in_order(root->lchild);
            print_node(root);
            output_k(root->rchild, k - SIZE(root->lchild) - 1);
        }
    }
    

    加上拓展后的完整代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    #define KEY(n) (n ? n->key : -1)
    #define SIZE(n) (n ? n->size : 0)
    
    typedef struct Node {
        int key, size;
        struct Node *lchild, *rchild;
    } Node;
    
    Node *getNewNode(int key) {
        Node *p = (Node *)malloc(sizeof(Node));
        p->key = key;
        p->size = 1;
        p->lchild = p->rchild = NULL;
    }
    
    void clear(Node *root) {
        if (root == NULL) {
            return ;
        }
        clear(root->lchild);
        clear(root->rchild);
        free(root);
        return ;
    }
    
    void update_size(Node *root) {
        root->size = SIZE(root->lchild) + SIZE(root->rchild) + 1;
    }
    
    Node *insert(Node *root, int key) {
        //root是空,则表明从根节点遍历到这个空节点都没有找到与参数key值一样的节点,可以在这里插入新节点,且插入后该节点为叶子节点
        if (root == NULL) {
            return getNewNode(key);
        }
        if (root->key == key) {//这里不重复插入相同key值得节点
            return root;
        }
        if (key < root->key) {//若插入key比当前节点的key小,则递归到当前节点的左子树中去插入
            root->lchild = insert(root->lchild, key);
        } else {//若插入key比当前节点的key大,则递归到当前节点的右子树中去插入
            root->rchild = insert(root->rchild, key);
        }
        update_size(root);
        return root;
    }
    
    Node *prodecessor(Node *root) {
        Node *p = root->lchild;
        while (p->rchild != NULL) {
            p = p->rchild;
        }
        return p;
    }
    
    Node *erase(Node *root, int key) {
        //root是空,则表明从根节点遍历到这个空节点都没有找到与参数key值一样的节点,直接返回
        if (root == NULL) {
            return root;
        }
        if (key < root->key) {//key值小于当前节点的key,则要删除的点在root的左子树上
            root->lchild = erase(root->lchild, key);
        } else if (key > root->key){//key值大于当前节点的key,则要删除的点在root的左子树上
            root->rchild = erase(root->rchild, key);
        } else {//key值与当前节点的key一样,则以度的数量开始区分删除情况。
            if (root->lchild == NULL || root->rchild == NULL) {//删除度为0或者1都可以这个分支。
                Node *p = root->lchild == NULL ? root->rchild : root->lchild;
                free(root);
                return p;
            } else {////度为2:直接转化为删除该节点的前驱节点
                Node *p = prodecessor(root);
                root->key = p->key;
                root->lchild = erase(root->lchild, p->key);
            }
        }
        update_size(root);
        return root;
    }
    
    void print_node(Node *root) {
        printf("(%d[%d]: %d, %d)
    ", KEY(root), SIZE(root), KEY(root->lchild), KEY(root->rchild));
    }
    
    void _in_order(Node *root) {
        if (root == NULL) {
            return ;
        }
        _in_order(root->lchild);
        print_node(root);
        _in_order(root->rchild);
        return ;
    }
    
    void in_order(Node *root) {
        printf("binary tree:
    ");
        _in_order(root);
        printf("
    
    ");
    }
    
    int find_k(Node *root, int k) {
        if (root == NULL || k == 0) {
            return -1;
        }
        if (k == SIZE(root->lchild) + 1) {//若root节点的左子树节点数量 + 1等于 k,则root节点就是第K个节点
            return root->key;
        }
        if (k <= SIZE(root->lchild)) {//若root节点的左子树节点数量大于等于k,则递归到左子树中去找第K个节点
            return find_k(root->lchild, k);
        }
        //若root左子树节点数量 + 1小于K,则递归到右子树中去找右子树中第K - size(L(root)) - 1个节点。
        if (k > SIZE(root->lchild) + 1) {
            return find_k(root->rchild, k - SIZE(root->lchild) - 1);
        }
    }
    
    void menu(void) {
        printf("Please enter the operation: 
    ");
        printf("Press 1 to insert a node to binary search tree
    ");
        printf("Press 2 to delete a node from binary search tree
    ");
        printf("Press 3 to find a node from binary search tree
    ");
        printf("Press 4 to output top-k sequence from binary search tree
    ");
        printf("Press TRL + D to quit!
    ");
    }
    
    int main() {
        Node *root = NULL;
        int op, val;
        menu();
        while (~scanf("%d", &op)) {
            if (op < 1 || op > 4) {
                printf("please enter the right operation!
    ");
                continue;
            }
            switch (op) {
                case 1:
                    printf("Enter the key you want to insert: ");
                    scanf("%d", &val);
                    root = insert(root, val);
                break;
    
                case 2:
                    printf("Enter the key you want to delete: ");
                    scanf("%d", &val);
                    root = erase(root, val);
                break;
    
                case 3:
                    printf("Enter the index you are looking for:");
                    scanf("%d", &val);
                    printf("Find NO.%d of the binary tree, result: %d
    
    ", val, find_k(root, val));
                break;
    
                case 4:
                    printf("Enter a k for output top-k sequence: ");
                    scanf("%d", &val);
                    output_k(root, val);
                    printf("
    ");
                break;
            }
            if (op != 3 && op != 4) {
                in_order(root);
            }
            menu();
        }
        clear(root);
        return 0;
    }
    
    测试结果
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press 3 to find a node from binary search tree
    Press 4 to output top-k sequence from binary search tree
    Press TRL + D to quit!
    1
    Enter the key you want to insert: 12
    binary tree:
    (12[1]: -1, -1)
    
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press 3 to find a node from binary search tree
    Press 4 to output top-k sequence from binary search tree
    Press TRL + D to quit!
    1
    Enter the key you want to insert: 8
    binary tree:
    (8[1]: -1, -1)
    (12[2]: 8, -1)
    
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press 3 to find a node from binary search tree
    Press 4 to output top-k sequence from binary search tree
    Press TRL + D to quit!
    1
    Enter the key you want to insert: 10
    binary tree:
    (8[2]: -1, 10)
    (10[1]: -1, -1)
    (12[3]: 8, -1)
    
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press 3 to find a node from binary search tree
    Press 4 to output top-k sequence from binary search tree
    Press TRL + D to quit!
    1
    Enter the key you want to insert: 9
    binary tree:
    (8[3]: -1, 10)
    (9[1]: -1, -1)
    (10[2]: 9, -1)
    (12[4]: 8, -1)
    
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press 3 to find a node from binary search tree
    Press 4 to output top-k sequence from binary search tree
    Press TRL + D to quit!
    1
    Enter the key you want to insert: 34
    binary tree:
    (8[3]: -1, 10)
    (9[1]: -1, -1)
    (10[2]: 9, -1)
    (12[5]: 8, 34)
    (34[1]: -1, -1)
    
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press 3 to find a node from binary search tree
    Press 4 to output top-k sequence from binary search tree
    Press TRL + D to quit!
    1
    Enter the key you want to insert: 23
    binary tree:
    (8[3]: -1, 10)
    (9[1]: -1, -1)
    (10[2]: 9, -1)
    (12[6]: 8, 34)
    (23[1]: -1, -1)
    (34[2]: 23, -1)
    
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press 3 to find a node from binary search tree
    Press 4 to output top-k sequence from binary search tree
    Press TRL + D to quit!
    1
    Enter the key you want to insert: 20
    binary tree:
    (8[3]: -1, 10)
    (9[1]: -1, -1)
    (10[2]: 9, -1)
    (12[7]: 8, 34)
    (20[1]: -1, -1)
    (23[2]: 20, -1)
    (34[3]: 23, -1)
    
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press 3 to find a node from binary search tree
    Press 4 to output top-k sequence from binary search tree
    Press TRL + D to quit!
    1
    Enter the key you want to insert: 18
    binary tree:
    (8[3]: -1, 10)
    (9[1]: -1, -1)
    (10[2]: 9, -1)
    (12[8]: 8, 34)
    (18[1]: -1, -1)
    (20[2]: 18, -1)
    (23[3]: 20, -1)
    (34[4]: 23, -1)
    
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press 3 to find a node from binary search tree
    Press 4 to output top-k sequence from binary search tree
    Press TRL + D to quit!
    1
    Enter the key you want to insert: 17
    binary tree:
    (8[3]: -1, 10)
    (9[1]: -1, -1)
    (10[2]: 9, -1)
    (12[9]: 8, 34)
    (17[1]: -1, -1)
    (18[2]: 17, -1)
    (20[3]: 18, -1)
    (23[4]: 20, -1)
    (34[5]: 23, -1)
    
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press 3 to find a node from binary search tree
    Press 4 to output top-k sequence from binary search tree
    Press TRL + D to quit!
    1
    Enter the key you want to insert: 19
    binary tree:
    (8[3]: -1, 10)
    (9[1]: -1, -1)
    (10[2]: 9, -1)
    (12[10]: 8, 34)
    (17[1]: -1, -1)
    (18[3]: 17, 19)
    (19[1]: -1, -1)
    (20[4]: 18, -1)
    (23[5]: 20, -1)
    (34[6]: 23, -1)
    
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press 3 to find a node from binary search tree
    Press 4 to output top-k sequence from binary search tree
    Press TRL + D to quit!
    1
    Enter the key you want to insert: 21
    binary tree:
    (8[3]: -1, 10)
    (9[1]: -1, -1)
    (10[2]: 9, -1)
    (12[11]: 8, 34)
    (17[1]: -1, -1)
    (18[3]: 17, 19)
    (19[1]: -1, -1)
    (20[5]: 18, 21)
    (21[1]: -1, -1)
    (23[6]: 20, -1)
    (34[7]: 23, -1)
    
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press 3 to find a node from binary search tree
    Press 4 to output top-k sequence from binary search tree
    Press TRL + D to quit!
    1
    Enter the key you want to insert: 25
    binary tree:
    (8[3]: -1, 10)
    (9[1]: -1, -1)
    (10[2]: 9, -1)
    (12[12]: 8, 34)
    (17[1]: -1, -1)
    (18[3]: 17, 19)
    (19[1]: -1, -1)
    (20[5]: 18, 21)
    (21[1]: -1, -1)
    (23[7]: 20, 25)
    (25[1]: -1, -1)
    (34[8]: 23, -1)
    
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press 3 to find a node from binary search tree
    Press 4 to output top-k sequence from binary search tree
    Press TRL + D to quit!
    1
    Enter the key you want to insert: 28
    binary tree:
    (8[3]: -1, 10)
    (9[1]: -1, -1)
    (10[2]: 9, -1)
    (12[13]: 8, 34)
    (17[1]: -1, -1)
    (18[3]: 17, 19)
    (19[1]: -1, -1)
    (20[5]: 18, 21)
    (21[1]: -1, -1)
    (23[8]: 20, 25)
    (25[2]: -1, 28)
    (28[1]: -1, -1)
    (34[9]: 23, -1)
    
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press 3 to find a node from binary search tree
    Press 4 to output top-k sequence from binary search tree
    Press TRL + D to quit!
    2
    Enter the key you want to delete: 17
    binary tree:
    (8[3]: -1, 10)
    (9[1]: -1, -1)
    (10[2]: 9, -1)
    (12[12]: 8, 34)
    (18[2]: -1, 19)
    (19[1]: -1, -1)
    (20[4]: 18, 21)
    (21[1]: -1, -1)
    (23[7]: 20, 25)
    (25[2]: -1, 28)
    (28[1]: -1, -1)
    (34[8]: 23, -1)
    
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press 3 to find a node from binary search tree
    Press 4 to output top-k sequence from binary search tree
    Press TRL + D to quit!
    3
    Enter the index you are looking for:4
    Find NO.4 of the binary tree, result: 12
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press 3 to find a node from binary search tree
    Press 4 to output top-k sequence from binary search tree
    Press TRL + D to quit!
    3
    Enter the index you are looking for:10
    Find NO.10 of the binary tree, result: 25
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press 3 to find a node from binary search tree
    Press 4 to output top-k sequence from binary search tree
    Press TRL + D to quit!
    4
    Enter a k for output top-k sequence: 7
    (8[3]: -1, 10)
    (9[1]: -1, -1)
    (10[2]: 9, -1)
    (12[12]: 8, 34)
    (18[2]: -1, 19)
    (19[1]: -1, -1)
    (20[4]: 18, 21)
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press 3 to find a node from binary search tree
    Press 4 to output top-k sequence from binary search tree
    Press TRL + D to quit!
    4
    Enter a k for output top-k sequence: 3
    (8[3]: -1, 10)
    (9[1]: -1, -1)
    (10[2]: 9, -1)
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press 3 to find a node from binary search tree
    Press 4 to output top-k sequence from binary search tree
    Press TRL + D to quit!
    4
    Enter a k for output top-k sequence: 4
    (8[3]: -1, 10)
    (9[1]: -1, -1)
    (10[2]: 9, -1)
    (12[12]: 8, 34)
    
    Please enter the operation:
    Press 1 to insert a node to binary search tree
    Press 2 to delete a node from binary search tree
    Press 3 to find a node from binary search tree
    Press 4 to output top-k sequence from binary search tree
    Press TRL + D to quit!
    

    原创博文,转发请加上原链接

  • 相关阅读:
    AcWing 157. 树形地铁系统 (hash判断树同构)打卡
    AcWing 156. 矩阵 (哈希二维转一维查询)打卡
    AcWing 144. 最长异或值路径 01字典树打卡
    AcWing 143. 最大异或对 01字典树打卡
    AcWing 142. 前缀统计 字典树打卡
    AcWing 139. 回文子串的最大长度 hash打卡
    AcWing 138. 兔子与兔子 hash打卡
    常用C库函数功能及用法
    编程实现C库函数
    C语言面试题5
  • 原文地址:https://www.cnblogs.com/ydqblogs/p/14676077.html
Copyright © 2011-2022 走看看