有序表

在哈希表的基础上,内部key是有序的,所有操作的时间复杂度都是O(logN)级别的

  • 红黑树
  • AVL树
  • set-balance tree
  • 跳表skiplist(单链表改写)

以上都是有序表,实现原理不一样,但实现的结果操作的时间复杂度都是一样的,可能常数时间有差异,但差异很小

搜索二叉树

默认搜索二叉树上没有重复值(有重复值的话添加统计数据项即可)

添加操作

第一个进来就是头节点,然后往后进来的小的就放左边,大的放右边,每棵子树都这样操作就行

查询操作

找小于等于6的最近节点,从头节点出发,4小于6,往右树走,8大于6,往左树走,7大于6,继续往左树走,5小于6,往右树走,发现为空,返回5

删除操作

  1. 要删除的节点没有左孩子也没有右孩子,直接删掉释放掉就行

  2. 要删除的节点只有左孩子或者只有右孩子,让其孩子替代他就行

  3. 要删除的节点左右孩子都有,可以让左树上的最右节点或者右树上的最左节点来替换

    比如找到右树上的最左节点,然后如果该节点有右孩子的话直接把右孩子整个给其父节点,然后把最左节点移到要删除的节点的位置

平衡性

没有平衡性没法保证以上操作时间复杂度都是O(logN)级别

狭义的平衡二叉树

左右两棵子树高度不超过1

广义的平衡二叉树

左右两棵子树的高度不相差太大即可,这样也是O(logN)的级别

AVL树严格要求左右两棵子树的高度不超过1

左旋、右旋

头节点往左倒,节点F给到节点A的右节点

右旋同理

AVL

AVL树的增删改查操作与搜索二叉树一样

但它是通过每加入、删除一个节点时,看加入节点到头节点之间每个节点是否有平衡性来检查整棵树是否有平衡性(删除的时候,如果是左右孩子都有的情况,检查是从删除节点的右子树上的最左节点一路往上)

四种没有平衡性的结构

LL与RR

左树上的左孩子过长或者右树上的右孩子过长

头节点右旋或左旋即可

LR、RL

左树上的右孩子过长或者右树上的左孩子过长

想办法把节点X转成头部

public void rebalance(AVLNode node){while(node!=null){Node parent=node.parent;int leftHeight=(node.left==null)?-1:((AVLNode)node.left).height;int rightHeight=(node.right==null)?-1:((AVLNode)node.right).height;int nodeBalance=rightHeight-leftHeight;if(nodeBalance==2){if(node.right.right!=null){node=(AVLNode)avlRotateLeft(node);//RR  旋转里面有更新高度的操作break;}else{node=(AVLNode)doubleRotateRightLeft(node);//RLbreak;}}else if(nodeBalance==-2){if(node.left.left!=null){node=(AVLNode)avlRotateRight(node);//LLbreak;}else{node=(AVLNode)doubleRotateLeftRight(node);//LRbreak;}}else{updateHeight(node);//更新高度}node=(AVLNode)parent;//node往上查是否平衡}
}

AVL与红黑树、SB树的区别

红黑树和SB树的增删改查操作、检查时机都与AVL树一样

唯一的区别是具体检查每一个节点的时候的违规条件不一样以及AVL树维持的是高度信息、红黑树和SB树(节点数量、大小)维持的是其他信息

实现平衡性的方式也是通过左旋和右旋

SB树

平衡性:

  • 每棵子树的大小,不小于其兄弟的子树大小
  • 既每棵叔叔树的大小,不小于其任何侄子树的大小

这样的话左右孩子高度差不会相差很多,最多是两倍+1

一样是四种不平衡的情况

LL、RR

假设现在L的左子树A的节点个数大于R的节点个数

  1. 让节点T右旋
  2. 然后看谁的子节点发生了变化:L和T
  3. 对L和T做递归判断

LR、RL

LR:L的右子树B(左孩子的右子树)的节点个数大于R的节点个数

把B搞成头节点

然后看哪些节点的左右孩子发生了变化就递归

private SBTNode<K, V> matain(SBTNode<K, V> cur) {if (cur == null) {return null;}if (cur.l != null && cur.l.l != null && cur.r != null && cur.l.l.size > cur.r.size) {cur = rightRotate(cur);cur.r = matain(cur.r);cur = matain(cur);} else if (cur.l != null && cur.l.r != null && cur.r != null && cur.l.r.size > cur.r.size) {cur.l = leftRotate(cur.l);cur = rightRotate(cur);cur.l = matain(cur.l);cur.r = matain(cur.r);cur = matain(cur);} else if (cur.r != null && cur.r.r != null && cur.l != null && cur.r.r.size > cur.l.size) {cur = leftRotate(cur);cur.l = matain(cur.l);cur = matain(cur);} else if (cur.r != null && cur.r.l != null && cur.l != null && cur.r.l.size > cur.l.size) {cur.r = rightRotate(cur.r);cur = leftRotate(cur);cur.l = matain(cur.l);cur.r = matain(cur.r);cur = matain(cur);}return cur;
}

红黑树

  1. 每个节点存一个颜色信息,不是黑就是红
  2. 要求头节点和叶子节点(这里的叶子节点指的是传统的叶子节点再往下一层的空节点)都是黑的
  3. 红色的节点之间不相邻
  4. 对任何一颗子树来说,从某一个头部cur出发到叶子节点的路径上要求黑色的节点数量一样

在这样的四个要求的基础上

任何一颗子树的最长路径是红黑红黑这样特征的路径,最短的路径是全是黑的节点,而根据第四个要求可以得知,两条路径的长度相差不会超过两倍

因此能做到以上四个要求,红黑树基本上就是平衡的

跳表

加入一个节点时,先给该节点随机生成,看能生成几层(比如是0.5的概率生成,0.5的概率不生成,一直随机到不生成层数为止),然后从最高层开始往下,找到小于等于该数的最近节点,如果该节点生成的层数没到这一层,就往下,在下一层就从上一层找到的最近节点开始找小于等于的新的最近节点,直到该节点生成的层数到了,才开始挂,这样的过程,就跳过了很多实际上不需要遍历的对象,提升了有序链表的加入、查询速度

删除的过程就是先查询,看该节点是否存在,存在的话就删除,把要删除的节点的前面和后面连上就行了

第0层一定存在所有节点(第零层就是传统的单链表+有序)

时间复杂度:

每次加一个节点的时候加层数的时候概率都是0.5,即数据量大的时候,每一层的节点数量就类似一颗满二叉树

算法与数据结构——有序表(Java)(b站左程云课程笔记总结)相关推荐

  1. 算法与数据结构——算法基础——二叉树(java)(b站左程云课程笔记整理)

    二叉树 了解一个二叉树的递归序.先序.中序.后序 递归序:每个数会被打印三次(可以理解为前中后) 先序:头左右 中序:左头右 后序:左右头 public static class Node {publ ...

  2. 算法与数据结构——算法基础——暴力递归(回溯)(java)(左程云b站课程总结)

    暴力递归 暴力递归就是尝试 类似于回溯:可以理解为回溯就是在暴力递归的基础上在每个操作步骤加上标记和取消标记的处理 把问题转化为规模缩小了的同类问题的子问题 有明确的不需要继续进行递归的条件(base ...

  3. B站左程云算法视频高级班01

    题目1:给定一个数组,求如果排序之后,相邻两数的最大差值,要求时间复杂度O(N),且要不能用非基于比较的排序 [               ]假设是长度为9的数组 首先遍历数组 找出min 和 ma ...

  4. B站左程云算法视频基础提升02

    岛问题 一个矩阵中只有0和1两种值,每个位置都可以和自己的上下左右相连,如果一片1连在一起,这个部分叫做一个岛,求一个矩阵有多少个岛 思路:遍历,infect class Solution {publ ...

  5. B站左程云算法视频笔记(01

    1.位运算 异或 ^ ,可理解为不进为相加,满足结合律和交换律 a^a=0: a^0=a: 交换a和b a=a^b: b=a^b: a=a^b: 但必须满足是位置不同的(同一内存位置自己异或结果为0) ...

  6. B站左程云算法视频笔记05

    大数据 有一个包含100亿个URL的大文件,假设每个URL占用64B,请找出其中所有重复的URL (布隆过滤器或者哈希函数分流) [补充]某搜索公司一天的用户搜索词汇是海量的(百亿数据量),请设计一种 ...

  7. B站左程云算法视频高级班05

    题目一:在一个无序数组中,求第k小的数 快排:荷兰国旗问题 BFPRT 有讲究的选择一个数 之后的步骤和快排一样 假设整个方法叫f函数 f(arr, k) 1)0~4一组 5~9一组 0~14一组 剩 ...

  8. CSDN专访左程云,算法之道

    算法的庞大让很多人畏惧,程序员如何正确的学习并应用于面试.工作中呢?今天,CSDN邀请了IBM软件工程师.百度软件工程师.刷题5年的算法热爱者左程云,来担任CSDN社区问答栏目的第二十六期嘉宾,届时会 ...

  9. 左程云算法笔记(四)哈希表和有序表的使用、链表

    左程云算法笔记(四) 哈希表的使用 有序表的使用 链表 单链表反转 (LC206) 双向链表反转 打印两个有序链表的公共部分 合并两个有序链表(LC21) 判断一个链表是否为回文结构 (LC234) ...

  10. 一看“左程云:200道算法与数据结构”,二刷“阿里云:70+算法题、30种大厂笔试高频知识点”,3月过去终于挺进我梦中的字节!

    不管是学生还是已经工作的人,我想彼此都有一个相同的梦想:进大厂! 眼看着2020年还有个三十来天就要完美收尾了,那么如何才能在未来三个月弯道超车赶上"金三银四的春招",进入梦寐以求 ...

最新文章

  1. mac osx 上Eclipse/CDT问题及解决方案
  2. python学习高级篇(part6)--内置函数dir
  3. 人工智能在建筑运营_打造智能建筑商
  4. SharePoint2007安装图文详解二:安装AD(活动目录)及DNS
  5. 你觉得外观模式和代理模式的联系和区别是什么?_GoF23种设计模式
  6. python环境变量的配置 alias_配置别名
  7. 链表插入功能实现演示
  8. vt linux tty中文,Linux输入子系统和tty关系影述
  9. 一个农民父亲令人震撼的力量
  10. 操作系统-单处理器调度
  11. miui通知栏要点两下_「MIUI玩机技巧56」小米应用商店 新增 通知栏快捷入口
  12. numpy random 模块
  13. 智能门禁考勤机:刷脸同时开门和打卡
  14. 加速网站速度的最佳做法_(2)把样式表放在顶部
  15. 【物流选址】基于matlab佛洛依德算法求解物流选址问题【含Matlab源码 892期】
  16. 椭圆函数与模函数(2012.10出版)(2013-01-16 09:34:57)
  17. 从卫星影像的视角见证莆田母亲河(美丽的木兰溪)改造前后的容颜变化
  18. Java实现新浪微博第三方登录
  19. CAS单点登录-密码管理(十三)
  20. 【Mysql】1366 - Incorrect string value: ‘\xE9\x92\xB1\xE7\x94\xB5‘

热门文章

  1. 酒店管理系统软件服务器端,酒店管理系统erp
  2. Vue中使用froala富文本编辑器制作打印模板 + print.js 打印
  3. VoLTE业务端到端流程:无线侧信令流程
  4. 【科研绘图】沐风老师3DMAX极小曲面建模教程
  5. 非常好用的自助建站程序整站源码 内置几十种站
  6. Excel多级下拉菜单的制作
  7. PPT:人工智能在物流与供应链中的应用
  8. React Native多语言切换
  9. 信号与系统速成和课后作业
  10. 【Ubuntu18.04安装搜狗中文输入法】