zoukankan      html  css  js  c++  java
  • 【模板】二叉搜索树

    二叉搜索树:对于二叉树中的任意节点,左子树中所有的值都小于当前位置的值,右子树中所有的值都大于当前位置的值。

    操作:

    1.插入一个数值。

    2.查询是否包含某个数值。

    3.删除某个数值。

    插入和查找是差不多的,都是比当前值(要找的值)大就往左走,否则就往右走,直到找到为止。

    最复杂的操作是删除某个节点,不过可以分为3种情况来讨论:

    1.需要删除的节点没有左子树,那就把右子树提上去。

    2.需要删除的节点的左子树没有右子树,那就把左子树提上去。

    3.其他情况,把左子树中最大的节点提到当前删除的节点的位置。

    所有操作的时间复杂度都是O(log(n))。

    还是比较高效的一种数据结构。

    代码:

    #include <iostream>
    #include <algorithm>
    #include <map>
    #include <vector>
    #include <set>
    #include <math.h>
    #include <queue> 
    using namespace std;
    typedef long long ll;
    #define INF 2147483647
    
    //表示节点的结构体 
    struct node{
        int val;
        node *lch, *rch;
    };
    
    //如果小于当前节点往左走,否则往右走,直到走到空为止,把要插入的节点放在这。
    //返回值意义是更新当前子树,想象一下从最下层开始返回的情况。 
    node *insert(node *p,int x){
        if(p == NULL){
            node *q = new node;
            q->val = x;
            q->lch = q->rch = NULL;
            return q;
        }else{
            if(x < p->val) p->lch = insert(p->lch, x);
            else p->rch = insert(p->rch, x);
            return p;
        }
    }
    
    //查找数值x。
    //每一个节点当做一棵子树,如果当前节点不是就找它的左右子树。 
    bool find(node *p,int x){
        if(p == NULL) return false;
        else if(x == p->val) return true;
        else if(x < p->val) return find(p->lch, x);
        else return find(p->rch, x);
    }
    
     
    node *remove(node *p, int x){
        if(p == NULL) return NULL;        //当前子树没有找到,如果一个节点的左右子树都返回NULL表明当前子树没有找到 
        else if(x < p->val) p->lch = remove(p->lch, x);   //向左走 
        else if(x > p->val) p->rch = remove(p->rch, x);        //向右走 
        //以下为找到了的情况 
        //左子树为空,先保存右子树,再删除当前节点,把右子树直接挂在删除节点的原先位置。 
        else if(p->lch == NULL){        
            node *q = p->rch;
            delete p;
            return q;
        //左子树的右子树为空,把删除节点的左子树挂在当前位置,把删除节点的右子树挂在当前位置的右边 
        //这样保证了搜索树的性质 
        }else if(p->lch->rch == NULL){
            node *q = p->lch;
            q->rch = p->rch;
            delete p;
            return q;
        }else{
            //找到删除节点左子树的最右边的节点,即左子树中的最大值 q->rch 
            node *q;
            for(q = p->lch;q->rch->rch != NULL; q = q->rch);
            //把最大值节点q->rch用r保存下来,把最大值节点的左子树提上来 
            node *r = q->rch;
            q->rch = r->lch;
            //把最大值节点r放在了原先删除节点的位置 
            r->lch = p->lch;
            r->rch = p->rch;
            delete p;
            return r;
        }
        return p;
    }
    
    int main(){
    
        return 0;
    } 
  • 相关阅读:
    最小生成树模板(Prim+Kruskal)
    最短路模板(Dij+Floyd)
    LeetCode双周赛#33 题解
    CSS3 学习笔记(中)
    拓扑排序小测试
    串和矩阵压缩的小测试
    树的相关小测试 题解
    Leetcode 周赛#202 题解
    HTML5 学习笔记
    Leetcode 双周赛#32 题解
  • 原文地址:https://www.cnblogs.com/zhangjiuding/p/7768852.html
Copyright © 2011-2022 走看看