zoukankan      html  css  js  c++  java
  • 第五篇、C_二叉搜索树

    1.二叉树的查找功能的时间复杂度比链表的好

    2.删除节点的稍微复杂点

      >没有节点,直接删除

      >只有左节点(或者右节点),直接用该节点的左节点(或者右节点)替代要删除的节点

      >有左节点并且有右节点,用左节点替代

    3.二叉树的遍历方式:

    /*
    1.中序遍历的递归算法定义:
    
        若二叉树非空,则依次执行如下操作:
    
        ⑴遍历左子树;
    
        ⑵访问根结点;
    
        ⑶遍历右子树。[3]
    
    2.先序遍历的递归算法定义:
    
        若二叉树非空,则依次执行如下操作:
    
        ⑴ 访问根结点;
    
        ⑵ 遍历左子树;
    
        ⑶ 遍历右子树。
    
    3.后序遍历得递归算法定义:
    
        若二叉树非空,则依次执行如下操作:
    
        ⑴遍历左子树;
    
        ⑵遍历右子树;
    
        ⑶访问根结点
    */
    typedef struct node{
        int num;
        struct node *left;
        struct node *right;
    }Node;
    
    typedef struct {
        Node *root;
    }Tree;
    
    /**
    *@brief 建树
    */
    Tree *createTree()
    {
        Tree *tree = malloc(sizeof(Tree));
        tree -> root = NULL;
        return tree;
    }
    
    /**
    *@brief 建树的节点
    */
    Node *createNode(int num)
    {
        Node *node = malloc(sizeof(Node));
        node -> num = num;
        node -> left = NULL;
        node -> right = NULL;
        return node;
    }
    
    /**
    *@brief 非递归插入
    */
    void insert(Tree *tree,int n)
    {
        if(tree -> root == NULL){
            tree -> root = createNode(n);
        }else{
            Node *p = tree -> root;
            Node *parent = NULL;
            while(p != NULL)
            {
                parent = p; // 记录当前移动的位置
                if(p -> num < n)
                {
                    p = p -> left;
                }
                else if(p -> num > n)
                {
                    p = p -> right;
                }
                else{ // 相等就不再插入
                    return;
                }
                
            }
            
            // 找到位置后插入
            if (n < parent -> num)
            {
                parent -> left = createNode(n);
            }else{
                parent -> right = createNode(n);
            }
        }
    }
    
    /**
    *@brief 递归插入
    */
    void insert(Node *node,int n)
    {
        if(node == NULL){
            node = createNode(n);
        }
        else if(n < node-> num){
            node -> left = insert(node -> left, n);    
        }
        else{
            node -> right = insert(node -> right, n);    
        }
    }
    
    /**
    *@brief 查找
    */
    Node *search(Tree tree,int n)
    {
        Node *p = tree -> root;
        while(p != NULL)
        {
            if(n < p -> num)
            {
                p = p -> left;
            }
            else if (n > p -> num)
            {
                p = p -> right;
            }
            else { 
                return p;
            }
        }
        return NULL;
    }
    
    /*
    1.中序遍历的递归算法定义:
    
        若二叉树非空,则依次执行如下操作:
    
        ⑴遍历左子树;
    
        ⑵访问根结点;
    
        ⑶遍历右子树。[3]
    
    2.先序遍历的递归算法定义:
    
        若二叉树非空,则依次执行如下操作:
    
        ⑴ 访问根结点;
    
        ⑵ 遍历左子树;
    
        ⑶ 遍历右子树。
    
    3.后序遍历得递归算法定义:
    
        若二叉树非空,则依次执行如下操作:
    
        ⑴遍历左子树;
    
        ⑵遍历右子树;
    
        ⑶访问根结点
    */
    
    
    
    /**
    *@brief 先序遍历
    *@param node tree->root
    */
    void preOrder(Node *node)
    {
        if (node != NULL)
        {
            printf("%d",node -> num);
            preOrder(node -> left);
            preOrder(node -> right);
        }
    }
    
    /**
    *@brief 中序遍历
    */
    void inOrder(Node *node)
    {
        if (node != NULL)
        {
            inOrder(node -> left);
            printf("%d",node -> num);
            inOrder(node -> right);
        }
    }
    
    /**
    *@brief 后序遍历
    */
    void tailOrder(Node *node)
    {
        if (node != NULL)
        {
            tailOrder(node -> left);
            tailOrder(node -> right);
            printf("%d",node -> num);
        }
    }
    
    /**
    *@brief 删除节点
    1//只有左节点,则左节点代替他的位置
    2//只有右节点,则右节点代替他的位置
    3//既有左节点又有右节点,则左子树的最右节点代替原节点
    */ bool deleteNode(Node *node,int n) { Node *p = node; Node *q; int temp; while(p != NULL && n != p -> num) { q = p; if(p -> num < n) { p = p -> left; } else if(p -> num > n) { p = p -> right; } else{ // 相等就不再插入 } } if(p == NULL){ printf("没有此元素"); } else{ // 如果找到要删除的节点 // 1.如果找到的节点,没有左子树和右子树 if(p -> left == NULL && P -> right == NULL) { if(p == q -> left) { q -> left = NULL; } if(p == q -> right) { q -> right = NULL; } free(p); p == NULL; } // 2.找到节点,但是要删除的节点只有左子树或者右子树 // 2.1 只有左子树 else if (NULL == p -> right && NULL != p -> left) { if(p == q ->left) { q -> left = p -> left; }else if(p == q -> right) { q ->right = p -> left; } free(p); p = NULL; } // 2.2 只有右子树 else if (NULL != p -> right && NULL == p -> left) { if(p == q ->left) { q -> left = p -> right; }else if(p == q ->right) { q ->right = p -> right; } free(p); p = NULL; } // 3.如果查找到的节点,左右子树都有(本代码使用直接前驱,也可以使用直接后继) else if (NULL != P -> right && NULL != p -> left) { Node *s,sParent; sParent = p; s = sParent -> left; while (NULL != s -> right) // 找到p的直接前驱 { sParent = s; s = s -> right; } temp = s -> num; deleteNode(node,temp); // 递归 p -> num = temp; } } }
  • 相关阅读:
    MyBatis的分页插件PageHelper
    Mybatis的插件 PageHelper 分页查询使用方法
    textarea还剩余字数统计,支持复制粘贴的时候统计字数
    Mybatis——oracle——sql语句结尾不加;
    window.location.href和window.open的几种用法和区别
    window.location.href的用法(动态输出跳转)
    mybatis rownum Oracle 随机
    java 回车替换换行
    session 取
    socket编程浅知识
  • 原文地址:https://www.cnblogs.com/HJQ2016/p/5830359.html
Copyright © 2011-2022 走看看