平衡二叉树

平衡二叉树插入操作的详细过程图解

江枫思渺然 提交于 2020-03-30 00:32:20
二叉搜索树/二叉排序树/二叉查找树 是二叉树、任意结点的左子树的值均小于根节点的值,右子树均大于根节点的值 没有键值相等 平衡二叉树(AVL树) 定义 左右字数的高度差的绝对值不超过1,并且两子树都是平衡二叉树 没有键值相等 高度差,又名平衡因子,范围为[-1,0,1],在此规定==平衡因子 bf = 右子树的高度-左子树的高度== 插入操作 当有新的结点插入之前,该树一定是一个平衡二叉树 按照普通搜索树的方式插入结点cur 插入之后,调整cur的 parent.bf:插入到左边 bf --;插入到右边 bf++; bf变为3种值: (1)0:插入结束 (2)-1/1:调整 bf 的过程向上蔓延 (3 )-2/2:进行修复, 对失衡的情况进行修复 插入完成之后,该树依然是一个平衡二叉树 具体步骤 通过查找,找到key的合适的位置并将key插入(如果已经存在,则放弃查找) 设置并修改平衡因子 设置新插入的结点 cur 的平衡因子,新插入的结点的平衡因子是 0(未调整的),因为一定插入在叶子结点 修改 cur 的父节点 parent 的平衡因子 bf 如果cur是parent的左子树,parent.bf -= 1 如果cur是parent的右子树,parent.bf += 1 修改parent.bf 之后,parent.bf 的取值范围为 [-2,-1,0,1,2] 具体情况如下表:

说说红黑树——不谈操作,只讲理解

旧巷老猫 提交于 2020-03-24 05:21:41
一、前言   这几天想学一学红黑树这种数据结构,于是上网找了很多篇博客,初看吓了一跳,红黑树竟然如此复杂。连续看了几篇博客后,算是对红黑树有了一些了解,但是它的原理却并不是特别理解。网上的博客,千篇一律的都是在叙述红黑树的操作,如何插入节点、删除节点,旋转、变色等,只关注如何正确构建一棵红黑树,但是却很少提及为什么这么做。这篇博客我就来记录一些我所知道的红黑树中比较重要的东西,以及谈一谈我的理解。   我不会描述红黑树的具体实现,因为阅读红黑树具体实现的过程中,我发现这真的不是很重要,没有太大的意义(这绝对不是自我安慰⊙﹏⊙∥),真正重要的是红黑树的思想。如果想要了解红黑树的具体实现,建议阅读这篇文章: https://mp.weixin.qq.com/s/hGHJonK999TAVJakPDNAkg 二、正文   2.1 二叉搜索树和平衡二叉树   在谈二叉红黑树之前,先来说一说二叉搜索树以及平衡二叉树,因为平衡二叉树是为了弥补二叉搜索树而发明出来的,而红黑树又是为了弥补平衡二叉树。   (1)二叉搜索树   二叉搜索树比较简单,它是一棵二叉树,而且满足这样一个性质: 对于树上的每一个节点,它左子树上的节点的值都比它小,而右子树上的节点的值都比它大 。如下,就是一棵二叉搜索树:   当我们需要往一棵二叉搜索树中插入节点时,只需要从根节点开始,依次比较,若比根节点小,则向左走

数据结构——树的相关概念

强颜欢笑 提交于 2020-03-21 12:58:05
平衡二叉树和二叉查找树 至多有两个子节点的树成为二叉树 1)平衡二叉树 1)树的左右高度差不能超过1. 2)任何往下递归的左子树和右子树,必须符合第一条性质 3)没有任何节点的空树或只有跟节点的树也是平衡二叉树 树的节点Node是key value的形式。因为key可能不连续,甚至不是整数,所以我们没办法使用数组来表示,这个时候我们就可以用二叉查找树来实现 2)二叉查找树 树如其名,二叉查找树非常擅长数据查找。 二叉查找树额外增加了如下要求:它的左子树上所有节点的值都小于它,而它的右子树上所有节点的值都大于它。 查找的过程从树的根节点开始,沿着简单的判断向下走,小于节点值的往左边走,大于节点值的往右边走,直到找到目标数据或者到达叶子节点还未找到。 通常设计Node节点来表示key value这样的数据对 二叉查找树的insert package bobo.algo; // 二分搜索树 // 由于Key需要能够进行比较,所以需要extends Comparable<Key> public class BST<Key extends Comparable<Key>, Value> { // 树中的节点为私有的类, 外界不需要了解二分搜索树节点的具体实现 private class Node { private Key key; private Value value; private

剑指offer:平衡二叉树

风格不统一 提交于 2020-03-17 03:14:19
题目描述 输入一棵二叉树,判断该二叉树是否是平衡二叉树。 方法一 : 递归计算左右子树高度,并且判断左右子树是否也是平衡二叉树。 但这样判断上层结点时会重复遍历下层结点,增加开销。 # -*- coding:utf-8 -*- # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution: def IsBalanced_Solution(self, pRoot): # write code here if not pRoot: return True left=self.depth(pRoot.left) right=self.depth(pRoot.right) return abs(left-right)<=1 and self.IsBalanced_Solution(pRoot.left) and self.IsBalanced_Solution(pRoot.right) def depth(self,root): if root==None: return 0 return 1+max(self.depth(root.left),self.depth(root.right)) 方法二 : 如果改为从下往上遍历

二叉树的平衡检查、数字分类

浪子不回头ぞ 提交于 2020-03-09 10:49:58
1.在 Internet 中实现信息浏览查询服务的是(C) A DNS B FTP C WWW D ADSL 解析: WWW 是一种建立在 Internet 上的全球性的、交互的、动态的、多平台的、分布式的,超文本超媒体信息查询系统,也是建立在 Internet 上的一种网络服务。 2.在 OSI 分层模型中,把传输的比特流划分为帧,是哪一层的功能(C ) A 物理层 B 网络层 C 数据链路层 D 传输层 3.已知一个线性表(38,25,74,63,52,48),假定采用散列函数h(key) = key%7 计算散列地址,并散列存储在散列表A【0…6】中,若采用线性探测方法解决 冲突,则在该散列表上进行等概率成功查找的平均查找长度为 C A 1.5 B 1.7 C 2.0 D 2.3 解析: 4.标题:二叉树平衡检查 【二叉树平衡检查】 实现一个函数,检查二叉树是否平衡,平衡的定义如下,对于树中的任意一个结点,其两颗子树的高度差不超过1。 给定指向树根结点的指针TreeNode* root,请返回一个bool,代表这棵树是否平衡。 public class TreeNode { int val = 0 ; TreeNode left = null ; TreeNode right = null ; public TreeNode ( int val ) { this . val

白话平衡二叉树

眉间皱痕 提交于 2020-03-08 16:15:56
  对于我们做Java开发的程序员来,绝大多数时候我们并不需要自己去实现一个平衡二叉树的数据结构,很多用到二叉树的地方都是封装好的算法,我们只需要利用暴露出来的API就行了,那么对于平衡二叉树,虽然不需要去实现,但是理解原理对我们是很有帮助的,特别是底层如果使用了平衡二叉树,那么就能够清晰的知道他的性能。   那么我们怎么样去理解平衡二叉树呢?   我们都清楚,二叉树的查找性能最坏是链表查找,复杂度是O(1),而平衡二叉树的复杂度是log2(N),这在数据量比较大的情况下性能差距是很大的。所以我们就要尽量把树变成平衡二叉树,也就是所谓的高度平衡。最坏性能的情况是链表,对于这种数据结构来说,给我们感性的认识是这种数据结构很瘦,而满二叉树,完全二叉树很胖,因为胖,所以层数少,所以查找性能好。因此构建二叉树的时候要尽量做到很胖,而不要很瘦。这就是平衡二叉树。   另外,关于构建二叉树的时候,有什么左旋转,有旋转,什么LL,RR,LR,RL这几种型号,其实也不用去记这种结构,我们只需要知道,假如有3个节点的链表,顺序增大或者减小,我们要把这种结构的链表编程二叉树,只需要用手抓住中间节点向上提一下,让中间节点在上方,两头的节点在下方,这就是让我们的层数减少了1,也就是在插入的时候平衡因子为2的时候破坏平衡性的时候,向上一提,层数减少1,于是又回到了平衡二叉树。这里说的是3个节点的顺序链表(用

平衡二叉树(AVL树)

回眸只為那壹抹淺笑 提交于 2020-03-07 04:51:44
我们先看看二叉排序树可能的问题: 一个数列{1,2,3,4,5,6},要求创建一颗二叉排序树(BST), 并分析问题所在 上面这颗二叉排序树(BST) 存在的问题分析: 左子树全部为空,从形式上看,更像一个单链表. 插入速度没有影响 查询速度明显降低(因为需要依次比较), 不能发挥BST的优势,因为每次还需要比较左子树,其查询速度比单链表还慢 解决方案-平衡二叉树(AVL) 平衡二叉树基本介绍 平衡二叉树也叫平衡二叉搜索树(Self-balancing binary search tree)又被称为AVL树, 可以保证查询效率较高。 具有以下特点:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。平衡二叉树的常用实现方法有红黑树、AVL、替罪羊树、Treap、伸展树等。 如下图所示,前2个是AVL树,因为其左右2颗子树 高度差不超过一,第三个图不是AVL树,因为其左边树比右边树的高度超过了一 左旋卷,右旋转和双旋转 那么怎么样让一个数列,创建出对应的平衡二叉排序树呢? 左旋转如图: 当根节点的(右子树高度 - 左子树高度 > 1)时我们需要进行左旋转 左旋转步骤: 1. 创建一个新的节点newNode,让其值等于等于当前根节点的值 2. 把新节点的左子树设置成当前节点的左子树即 newNode.left = left 3.

剑指offer---平衡二叉树

断了今生、忘了曾经 提交于 2020-03-06 05:13:20
题目描述 输入一棵二叉树,判断该二叉树是否是平衡二叉树。 解题思路: 通过得出二叉树的高度,从而判断是否为平衡二叉树。 平衡二叉树: 是一棵二叉排序树,即二叉搜索树 每个结点的左右子树的高度相差不超过1。 平衡二叉树的介绍: 关于平衡二叉树 通过flag标志,在求二叉树的高度的时候,比较左右子树的高度相差值是否大于1。 剑指offer中题目: 关于求解树的高度: 剑指offer—二叉树的深度 //计算数的高度,并判断是否为平衡二叉树 int getDepth ( TreeNode * pRoot , bool & flag ) { if ( pRoot ) { int left_depth = getDepth ( pRoot - > left , flag ) ; int right_depth = getDepth ( pRoot - > right , flag ) ; if ( fabs ( left_depth - right_depth ) > 1 ) { flag = false ; } if ( left_depth < right_depth ) { return right_depth + 1 ; } else { return left_depth + 1 ; } } return 0 ; } //平衡二叉树 bool IsBalanced_Solution

110. 平衡二叉树

三世轮回 提交于 2020-03-04 20:45:41
给定一个二叉树,判断它是否是高度平衡的二叉树。 本题中,一棵高度平衡二叉树定义为: 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 示例 1: 给定二叉树 [3,9,20,null,null,15,7] 3 / 9 20 / 15 7 返回 true 。 示例 2: 给定二叉树 [1,2,2,3,3,null,null,4,4] 1 / \ 2 2 / \ 3 3 / 4 4 返回 false 。 题目来源 这道题好像用二叉树的套路模板同样可行 通常模板 public *** tree(TreeNode root){ if(root==null){} //操作处理 return tree(root.left)&&tree(root.right); } 对于平衡问题 一棵树是否平衡肯定要看他的子树是否平衡,引入 高度函数 这里对于每个节点,我们只用去他的最大高度即可。 public int heigh(TreeNode root){ if(root==null) { return 0; } else{ return 1+Math.max(heigh(root.left),heigh(root.right)); } } 接着判断平衡 标注是:左子树的最大高度-右子树的最大高度是否》2 并且看左右子树是否都是平衡的 public boolean isBalanced

红黑树基本操作

大城市里の小女人 提交于 2020-03-03 00:34:44
很早之前就想写一篇关于红黑树的文章,但是由于担心自己理解的不透彻,就一直不敢下笔。于是在重新看了很多篇文章和资料之后,决定彻彻底底的把红黑树搞清楚。也希望让你在面试中游刃有余。OK,废话不多说,开始今天的文章。 整篇文章的思路是这样的,红黑树其实就是一种数据结构,设计它的目的就是为了高效地进行增删改查,所以我们文章的顺序也会按照这个思路来进行。我们先从二叉查找树逐渐引入到红黑树,然后再详细的讲解。你如果看过其他文章想必也一定清楚,红黑树比较麻烦,希望你有点耐心,认真理解每一张图再往下分析。 一、二叉查找树 在正式开始了解红黑树之前呢,我们先来看一下二叉查找树的概念,从浅入深,希望你不要着急,下面就是是一颗二叉查找树: 从这张图我们会发现如下的规律: (1)左子树上所有节点的值均小于或等于它的根结点的值。 (2)右子树上所有节点的值均大于或等于它的根结点的值。 如果我们想要查找一个数字11,过程是怎么样的呢? 上面的过程已经很清晰了,在查找的时候,先与根节点比较,比根节点大则从右子树查找,比根节点小则从左子树查找,然后重复上面的过程,一直到找到我们需要的元素为止。 这个过程是查找操作,对于添加和删除呢?其实原理也是一样的,我们第一步就是找到我们需要插入的位置,然后把元素插入即可。这样看二叉查找树挺好的呀?别着急我们继续往下看这种情况。 如果我们在刚刚开始的时候还是以9为根节点