zoukankan      html  css  js  c++  java
  • 二叉搜索树

    二叉搜索树是一个链式结构的,快速的进行数据的查询,删除,插入操作的数据结构(lg(n)的时间复杂度)

    然而,上面这些所有的功能利用数组+类似快排的操作也能完成,为什么要用跟麻烦的二叉搜索树呢

    数组,是一开始就要开好的在内存中占用了一段连续的内存,如果一个程序,他平时的数据流量比较小,用数组的话就必须开到最大流量时的内存

    而我们的二叉搜索树是链式存储,并不需要连续的内存,这样就节省了程序运行时的内存消耗

     

    性质:

      一个点的所有左子树的值都比这个节点的值小,所有右子树的值都比这个节点的值大

      如果有特殊的需求(会出现两个相同的值)我们可以考虑让左子树的值都<=这个节点的值

    操作:

      插入:

        对于如果已有一颗二叉搜索树,我要把值x插入这棵二叉树中

        我们只需要从根节点开始比较,如果x < root则往左子树上插否则则往右子树上插

        直到我们发现我们要插的子树为空,那么把x放在这里就好了

        这个东西用递归实现

      查询:

        我要在树中查询值为x的节点,我们将x与根节点比较,如果 x < root就在左子树中找否则就在右子树中找

        当root == x时root就是要找的节点

      删除:

        假设要删除x节点

        x为叶子节点:直接删掉就好了

        x只有左子树或只有右子树:

          在网上看这个的时候感觉好多博客都没完全说清楚,我来一个详细的解释

          只有左子树:

            直接把这个节点删掉,然后把他的左子树(x_left)与原来连接原来连接这个节点的线连接到一起就行了

            那么如果原来x是fa_x的右子树,fa_x的右子树就是x_left

            因为x下的所有节点都>fa_x  所有x_left做fa_x的右子树是完全没有问题的

            是fa_x的左子树同理

          只有右子树同理

        x既有左子树又有右子树:

          这时我们在删掉x后要在右子树中找一个来替换x的位置

          要保证x的性质的话,我们只需要找到右子树中最小的(repl_x)那个即可

          因为repl_x > x左边所有的数而小于x右边所有的树

          把repl_x换过去之后,repl_x就空出来了对吧

          因为repl_x是右子树中最小的,那么他肯定没有左子树,这就是删除节点的前两中种情况了,按前两种情况删除repl_x即可

     

      总结:

        虽然说二叉搜索树的时间复杂度是(lg(n))但是从操作中可以看出来,我们的时间复杂度实际是O(tree_h)

        如果我插入这棵树的时候是按数值顺序插入的,那么这棵树就会退化成一个链表,时间复杂度退化成O(n)

        

        如果有人问,我们已经知道数值了,为什么还要查询这些东西?

        那么数值可以理解为主建或者说用户名

        跟这个主建所绑定的有其他的东西,比如年龄,学号之类的个人资料,这就是二叉搜索树的实际应用

        这也应该是为什么我们要保证玩游戏时用户名不能重复的原因,如果用户名重复。。。。查询个人信息的时候是返回哪个呢?

     

      代码:(下午再写,啦啦啦~)

     

  • 相关阅读:
    摘录一篇 这两天对SSO的认识
    获取文本框中的行
    在窗体数据源中过滤记录
    linux下访问windows的共享
    使用Form作Lookup其窗体位置设置
    窗体数据源连接技巧
    给动态创建的控件指定事件
    Object的使用技巧
    显示进度条SysOperationProgress
    如何解决下载的CHM文件无法显示网页问题
  • 原文地址:https://www.cnblogs.com/shensobaolibin/p/8078883.html
Copyright © 2011-2022 走看看