zoukankan      html  css  js  c++  java
  • c实现二叉搜索树的插入删除,搜索

    // 二叉搜索树,以特定的规则来进行构建
    // 1,所有节点中,该节点的左子树中的节点的键值 =< 该节点,右子树中节点的键值 >= 该节点.
    // 2,当进行一次中序遍历,则会得到升序排列
    
    #include <stdio.h>
    #include <stdlib.h>
    struct Node{
        int key;
        Node *parent, *left, *right;
    };
    
    Node *root, *NIL;
    
    
    void insert_node(int k){
        //插入节点,构建搜索树
        Node *z;
        z = (Node *)malloc(sizeof(Node));
        z -> key = k;
        z -> left = NIL;
        z -> right = NIL;
        Node *x = root;
        Node *y = NIL;
    7 
    22 20 15 21 50 49 51
    前序遍历: 22 20 15 21 50 49 51 
    中序遍历:15 20 21 22 49 50 51 
    后续遍历:15 21 20 49 51 50 22 
    删除节点后:
    前序遍历: 49 20 15 21 50 51 
    中序遍历:15 20 21 49 50 51 
    后续遍历:15 21 20 51 50 49
        while(x != NIL){             //寻找适当节点插入
            y = x;
            if(z->key < x->key){
                x = x -> left;
            }else{
                x = x -> right;
            }
        }
    
        z -> parent = y;
        if(y == NIL){   //如果是null则为头节点
            root = z;
        }else{
            if(z -> key < y -> key){
                y -> left = z;
            }else{
                y -> right = z;
            }
        }
    }
    
    Node* search_node(int k, Node *node)
    {
        // 搜索指定元素
        while(node != NIL && node -> key != k){
            if(node -> key < k){
                node = node -> right;
            }else{
                node = node -> left;
            }
        }
        return node;
    }
    
    Node* treeMinimum(Node * node)
    {
        while(node->left != NIL){
            node = node -> left;                   
        } 
        return node;
    }
    
    Node* get_next_node(Node *node)
    {
        //获取中序遍历的下一个节点
        if(node -> right != NIL){
            // 如果该结点有右子节点,则找该右子节点最左侧的节点
            return treeMinimum(node -> right);
        }
        Node *y = node -> parent; //不存在右节点时,下一个节点就是,以左子节点身份出现的父节点
        while(y != NIL && y -> right == node){
            node = y;
            y = y -> parent;
        }
        return y;
    }
    void delete_node(Node *node)
    {
        Node *y; //要删除的对象
        Node *x; //y的子节点
    
        //确定要删除的节点
        if(node -> right == NIL || node -> left == NIL){
            y = node;
        }else{
            y = get_next_node(node);
        }
    
        // 确定y的子节点
        if(y -> left != NIL){
            x = y -> left;
        }else{
            x = y -> right;
        }
    
        if(x != NIL){
            x -> parent = y -> parent;
        }
    
        if (y -> parent == NIL){
            root = x;
        }else{
            if(y == y -> parent -> left){
                y -> parent -> left = x;
            }else{
                y -> parent -> right = x;
            }
        }
        printf("====%d", y->key);
        if(y != node){
            node -> key = y -> key;
        }
        
        free(y);
    }
    
    void norder_traversal(Node* node)
    {
        // 中序遍历
        if(node == NIL){
            return;
        }
        norder_traversal(node -> left);
        printf("%d ", node -> key);
        norder_traversal(node -> right);
    }
    
    void preorder_traversal(Node* node)
    {
        // 前序遍历
        if(node == NIL){
            return;
        }
        printf("%d ", node -> key);
        preorder_traversal(node -> left);
        preorder_traversal(node -> right);
    }
    
    void postorder_traversal(Node* node)
    {
        // 后续遍历
        if(node == NIL){
            return;
        }
        postorder_traversal(node -> left);
        postorder_traversal(node -> right);
        printf("%d ", node -> key);
    }
    
    
    
    int main(int argc, char const *argv[])
    {
        int n,element;
        scanf("%d", &n);
        for(int i = 0; i < n; i++){
            scanf("%d", &element);
            insert_node(element);
        }
        printf("前序遍历: ");
        preorder_traversal(root);
        printf("
    中序遍历:");
        norder_traversal(root);
        printf("
    后续遍历:");
        postorder_traversal(root);
        printf("
    ");
        Node *node = search_node(22, root);   //删除key为22的节点
        if(node != NIL){
            delete_node(node);
        }else{
            printf("no
    ");
        }
        printf("删除节点后:
    前序遍历: ");
        preorder_traversal(root);
        printf("
    中序遍历:");
        norder_traversal(root);
        printf("
    后续遍历:");
        postorder_traversal(root);
        printf("
    ");
        return 0;
    }
    /*
    测试数据
    7
    22 20 15 21 50 49 51
    */
    

    删除22节点后

    7 
    22 20 15 21 50 49 51
    前序遍历: 22 20 15 21 50 49 51 
    中序遍历:15 20 21 22 49 50 51 
    后续遍历:15 21 20 49 51 50 22 
    删除节点后:
    前序遍历: 49 20 15 21 50 51 
    中序遍历:15 20 21 49 50 51 
    后续遍历:15 21 20 51 50 49
    

    当树平衡的情况下,插入,删除,以及搜索,的复杂度,都是0(logn)

  • 相关阅读:
    JSON 语法
    AJAX 原理与使用
    SpringMVC MVC 架构模式
    HTTP 协议
    OSI 七层参考模型与 TCP/IP 四层协议
    MyBatis 延迟加载(十四)
    关于JVM调优
    mysql的锁
    spring boot启动原理
    redis相关问题解决
  • 原文地址:https://www.cnblogs.com/jlxa162hhf/p/14161255.html
Copyright © 2011-2022 走看看