AVL数
平衡二叉树(AVL树)
AVL树是一种二叉搜索树,并且每个节点的左右子树高度之差最多为1。AVL树是第一个在最坏的情况下保证以O(logn)的时间进行搜索,插入和删除操作的数据结构,AVL树能在对数时间内完成操作的主要思想是在插入和删除的时候花一些时间来保持树的平衡,使树的高度总在O(logn)范围内
插入后不满足AVL树的情况
令x是要插入AVL树种的关键字,首先将x插入树的底部,如果插入后仍是AVL树,则没有问题,否则要对数进行平衡。假设节点A的左子树和右子树在插入后失去平衡(高度差为2),这将分四种情况:
- 对A的左孩子的左子树进行了一次插入
- 对A的左孩子的右子树进行了一次插入
- 对A的右孩子的左子树进行了一次插入
- 对A的右孩子的右字树进行了一次插入
- 其中第一和第四种情形对称,第二和第三种情形对称,第一,四可以通过一次单旋转完成调整, - 下图是其中两种,剩两种与它们右对称  
- 图(a)插入新节点后,B树的高度是h+2,C树高度是h,为了保持树的平衡需要进行旋转,将B转到树顶,然后根据二叉搜索树的性质调整树的其他部分.
 
- 图(b)插入节点后,旋转一个位置不够,需要旋转两个位置. 首先对B进行顺时针旋转,然后对A作顺时针旋转
 - 顺时针和逆时针旋转两种方式:  - 双旋转的方式  (首先对B进行逆时针旋转,然后对A进行顺时针旋转) (首先对B进行逆时针旋转,然后对A进行顺时针旋转) (首先对B进行顺时针旋转,然后对A进行逆时针旋转) (首先对B进行顺时针旋转,然后对A进行逆时针旋转)- 上面两个例子中 A被称作关键节点 - 关键节点: 它是插入操作之后非AVL树的最小树的根节点,在插入节点之前必须找到关键节点,从而判断是哪种情况。于是我们在每个节点中记录一个平衡因子,即左右子树的高度之差.对AVL树而言,任意一个节点的平衡因子只能是1,-1或0. 关键节点的平衡因子一定不是0,并且在平衡后高度与插入前相同 
    - 源代码namespace AVLTree 
 {
 public class Node
 {
 public int Value;
 public Node Left;
 public Node Right;
 public int Factor; }
 public class AVLTree
 {
 private Node root; private Node ParentNode(int x)
 {
 Node node = root;
 Node parent = null;
 while (node != null)
 {
 if (node.Value == x)
 {
 return parent;
 } parent = node;
 if (node.Value > x)
 {
 node = node.Left;
 }
 else
 {
 node = node.Right;
 }
 }
 throw new Exception(string.Format("{0} has no parent", x));
 } public void Insert(int x)
 {
 Insert(ref root,x);
 } private void Insert(ref Node tree, int x)
 {
 Node node = new Node() { Value = x };
 if (tree == null)
 {
 tree = node;
 }
 if (tree.Value > x)
 {
 Insert(ref tree.Left,x); if (Depth(tree.Left) - Depth(tree.Right) == 2)
 {
 if (tree.Left.Value > x)
 {
 R_Rotate(tree);
 }
 else if (tree.Left.Value < x)
 {
 LR_Rotate(tree);
 }
 }
 } else if (tree.Value < x)
 {
 Insert(ref tree.Right,x); if (Depth(tree.Right) - Depth(tree.Left) == 2)
 {
 if (tree.Right.Value < x)
 {
 L_Rotate(tree);
 }
 else if (tree.Right.Value > x)
 {
 RL_Rotate(tree);
 }
 }
 }
 } public void L_Rotate(Node tree)
 {
 Node parent = ParentNode(tree.Value);
 Node lr = tree.Right;
 tree.Right = lr.Left; lr.Left = tree; if (parent != null)
 {
 if (Object.ReferenceEquals(parent.Left, tree))
 {
 parent.Left = lr;
 }
 else if (Object.ReferenceEquals(parent.Right, tree))
 {
 parent.Right = lr;
 }
 }
 else
 {
 root = tree;
 } } public void R_Rotate( Node tree)
 {
 Node parent = ParentNode(tree.Value);
 Node lc = tree.Left; tree.Left = lc.Right;
 lc.Right = tree; if (parent != null)
 {
 if (Object.ReferenceEquals(parent.Left, tree))
 {
 parent.Left = lc;
 }
 else if (Object.ReferenceEquals(parent.Right, tree))
 {
 parent.Right = lc;
 }
 }
 else
 {
 root = lc;
 }
 } public void LR_Rotate(Node tree)
 {
 L_Rotate(tree.Left);
 R_Rotate(tree);
 } public void RL_Rotate(Node tree)
 {
 R_Rotate(tree.Right);
 L_Rotate(tree);
 } private int Depth(Node tree)
 {
 if (tree == null) return 0;
 else
 {
 int dleft = Depth(tree.Left);
 int dright = Depth(tree.Right);
 return (dleft > dright ? dleft + 1 : dright + 1);
 }
 } public override string ToString()
 {
 return Tree(root);
 } private string Tree(Node node)
 {
 if (node == null)
 {
 return string.Empty;
 } string left = Tree(node.Left);
 string right = Tree(node.Right);
 if (!string.IsNullOrEmpty(left) || !string.IsNullOrEmpty(right))
 {
 return string.Format("{0}({1},{2})", node.Value, Tree(node.Left), Tree(node.Right));
 }
 else
 {
 return node.Value.ToString();
 }
 } public static void Swap(ref int x, ref int y)
 {
 int temp = x;
 x = y;
 y = temp;
 }
 }
 }
AVL数的更多相关文章
- 51nod  1412 AVL数的种类(DP
		题意给了n个节点 问AVL树的种类 卧槽 真的好傻 又忘记这种题可以打表了 就算n^3 也可以接受的 树的深度不大 那么转移方程很明显了 dp[i][j] 代表的是节点为n深度为j的树的种类 k ... 
- java平衡二叉树AVL数
		平衡二叉树(Balanced Binary Tree)具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树 右旋:在插入二叉树的时候,根节点的右侧高 ... 
- PAT甲级题解-1066. Root of AVL Tree (25)-AVL树模板题
		博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6803291.html特别不喜欢那些随便转载别人的原创文章又不给 ... 
- AVL平衡二叉搜索树原理及各项操作编程实现
		C语言版 #include<stdio.h> #include "fatal.h" struct AvlNode; typedef struct AvlNode *Po ... 
- BST AVL RBT B- B+ 的一些理解
		BST(二叉查找树,排序二叉树),如果数据有序的话,组成的二叉树会形成单列的形式,导致查询效率低AVL(平衡二叉树) 使树的左右高度差的绝对值不超过2,保证了查询效率.但是插入和删除会带来多次旋转,导 ... 
- 浅谈时间复杂度- 算法衡量标准Big O
		写在前面: 今天有一场考试,考到了Big-O的知识点,考到了一道原题,原题的答案我记住了,但实际题目有一些改动导致答案有所改动,为此作者决定重新整理一下复杂度相关知识点 Efficiency and ... 
- 《剑指offer(第二版)》面试题55——判断是否为平衡二叉树
		一.题目大意 输入一颗二叉树,判断该二叉树是否为平衡二叉树(AVL树). 二.题解 <剑指offer>上给出了两种解决方式: 1.第一种是从根节点开始,从上往下遍历每个子节点并计算以子节点 ... 
- 面试可能遇到的关联式容器(map、set等)相关问题
		>>>. map与set的区别是什么,各有哪些优势? map中存储的数据是以键值对(key - value)形式并且通过排序(比较key,默认以 '<' 方式排序)存在的( ... 
- Leetcode No.108 Convert Sorted Array to Binary Search Tree(c++实现)
		1. 题目 1.1 英文题目 Given an integer array nums where the elements are sorted in ascending order, convert ... 
随机推荐
- 那些年 IE 下踩过的坑
			1年过去了,换了一个不用兼容IE8一下浏览器的工作了! 1.:before,:after(伪类) 所有主流浏览器都支持 :before 选择器. 注释:对于 IE8 及更早版本中的 :before,必 ... 
- 优动漫PAINT漫画和插画方面软件特色
			优动漫PAINT也就是我们常说的clip studio paint(CSP)的中文版本,它是一款功能强大的漫画.插画绘制软件,它搭载了绘制漫画和插画所需的所有功能,包括丰富的笔工具.超强的笔压感应和手 ... 
- MyBatis 基础入门
			MyBatis 是一个半自动化的持久层的框架,能让开发者专注SQL本身 JDBC 连接数据库的硬编码问题,通过config,mapper配置文件解决 Mybatis开发需要关注的文件 l POJO类( ... 
- F5 datasheet
- springboot 打包下载数据
			//文件打包下载 public static HttpServletResponse downLoadFiles(List<File> files, Htt ... 
- [网络流24题] 最长k可重线段集问题 (费用流)
			洛谷传送门 LOJ传送门 最长k可重区间集问题的加强版 大体思路都一样的,不再赘述,但有一些细节需要注意 首先,坐标有负数,而且需要开$longlong$算距离 但下面才是重点: 我们把问题放到了二维 ... 
- linux chattr用法
			在linux中,我们有的时候发现linux无法删除一个文件或者目录. huskiesir第一次遇见这个问题还是在一次服务器被不法分子入侵之后的事情,我就发现某个进程很多,根据进程的名字,我搜索关键字找 ... 
- Centos6下创建Centos6基础镜像
			在centos6下可以使用官方仓库拉取一个指定系统类型跟tag的镜像到本地 [root@localhost ~]# docker pull centos:6.8 6.8: Pulling from c ... 
- Ubuntu下安装Tensorflow
			本文目录 引言 基于Anaconda的tensorflow安装 1 下载linux版本的Anaconda安装包 2 安装Anaconda 利用anaconda安装tensorflow 1 建立一个 c ... 
- 3、KOA模板引擎+访问静态资料中间件
			一.Koa模板引擎初识1.安装中间件 : npm i --save koa-views2.安装ejs模板引擎 :npm i --save ejs3.编写模板:<%= title %> 是调 ... 
