二叉树学习三:AVL树

  1、AVL树:

    1)其左子树(TL)与右子树(TR)是AVL树;

    2)|HL-HR|<=1,其中HL和HR是TL和TR的高度;

    3)高度为h的AVL树,结点数2*h-1。

    AVL树查找,插入,删除在平均和最坏情况下都是O(logn),插入和删除可能需要一次或多次旋转重新达到平衡。AVL树的旋转平衡思路:以不平衡点为根的子树高度应保持不变,新结点插入后,向根回溯到第一个原平衡因  子不为0的结点。旋转方法如下:

  1)LL型:左旋转

      

  2)RR型:右旋转

    

  3)LR型:在不平衡的儿结点先进行右旋转,然后进行左旋转。

    

  4)RL型:在不平衡的儿结点先进行左旋转,然后里德右旋转

    

  注意在旋转过程中涉及的最小树应该保持搜索二叉树的性质。

  AVL树的C++实现核心部分是平衡旋转:

  1 #include "stdafx.h"
  2 #include<time.h>
  3 #include<stdlib.h>
  4 #include<iostream>
  5 using namespace std;
  6
  7 typedef struct AVLTree{
  8     int ndata;
  9     AVLTree* pLchild;
 10     AVLTree* pRchild;
 11     int nheight;
 12 }AVLTree;
 13
 14 AVLTree* LLRotate(AVLTree* pRoot);
 15 AVLTree* RRRotate(AVLTree* pRoot);
 16 AVLTree* LRRotate(AVLTree* pRoot);
 17 AVLTree* RLRotate(AVLTree* pRoot);
 18
 19 int Compare(int a,int b){
 20     return(a > b ? a : b);
 21 }
 22 int Height(AVLTree* pRoot){
 23     if (NULL==pRoot)
 24     {
 25         return -1;
 26     }
 27     else
 28     {
 29         return(pRoot->nheight);
 30     }
 31 }
 32
 33 AVLTree* Insert(AVLTree* pRoot, int nData){
 34     if (NULL==pRoot)
 35     {
 36         pRoot = new AVLTree;
 37         pRoot->ndata = nData;
 38         pRoot->nheight = 0;
 39         pRoot->pLchild = NULL;
 40         pRoot->pRchild = NULL;
 41     }
 42     else if (pRoot->ndata>nData)
 43     {
 44         pRoot->pLchild = Insert(pRoot->pLchild, nData);
 45         if (Height(pRoot->pLchild) - Height(pRoot->pRchild)==2)
 46         {
 47             if (pRoot->pLchild->ndata>nData)
 48             {
 49                 pRoot = LLRotate(pRoot);
 50             }
 51             else
 52             {
 53                 pRoot = LRRotate(pRoot);
 54             }
 55         }
 56     }
 57     else if (pRoot->ndata<nData)
 58     {
 59         pRoot->pRchild = Insert(pRoot->pRchild, nData);
 60         if (Height(pRoot->pRchild) - Height(pRoot->pLchild) == 2)
 61         {
 62             if (pRoot->pRchild->ndata<nData)
 63             {
 64                 pRoot = RRRotate(pRoot);
 65             }
 66             else
 67             {
 68                 pRoot = RLRotate(pRoot);
 69             }
 70         }
 71     }
 72     pRoot->nheight = Compare(Height(pRoot->pLchild), Height(pRoot->pRchild)) + 1;
 73     return pRoot;
 74 }
 75
 76 //LL旋转
 77 AVLTree* LLRotate(AVLTree* pRoot){
 78     AVLTree* pTemp;
 79
 80     pTemp = pRoot->pLchild;
 81     pRoot->pLchild = pTemp->pRchild;
 82     pTemp->pRchild = pRoot;
 83
 84     pRoot->nheight = Compare(Height(pRoot->pLchild), Height(pRoot->pRchild)) + 1;
 85     pTemp->nheight = Compare(Height(pTemp->pLchild), pRoot->nheight) + 1;
 86     return pTemp;
 87 }
 88
 89 //RR旋转
 90 AVLTree* RRRotate(AVLTree* pRoot){
 91     AVLTree* pTemp;
 92
 93     pTemp = pRoot->pRchild;
 94     pRoot->pRchild = pTemp->pLchild;
 95     pTemp->pLchild = pRoot;
 96
 97     pRoot->nheight = Compare(Height(pRoot->pLchild), Height(pRoot->pRchild)) + 1;
 98     pTemp->nheight = Compare(Height(pTemp->pRchild), pRoot->nheight) + 1;
 99     return pTemp;
100 }
101
102 //LR旋转
103 AVLTree* LRRotate(AVLTree* pRoot){
104     pRoot->pLchild = RRRotate(pRoot->pLchild);
105     return LLRotate(pRoot);
106 }
107
108 //RL旋转
109 AVLTree* RLRotate(AVLTree* pRoot){
110     pRoot->pRchild = LLRotate(pRoot->pRchild);
111     return RRRotate(pRoot);
112 }
113
114 //输出树
115 void PrintTree(AVLTree* pRoot){
116     if (NULL==pRoot)
117     {
118         return;
119     }
120     static int n = 0;
121     PrintTree(pRoot->pLchild);
122     cout << ++n << "\t" << pRoot->ndata << "\t" << pRoot->nheight << "\n";
123     PrintTree(pRoot->pRchild);
124 }
125
126 int main()
127 {
128     AVLTree* pRoot = NULL;
129     srand((unsigned int)time(NULL));
130     for (int i = 0; i < 10; i++)
131     {
132         pRoot = Insert(pRoot, rand() % 100);
133     }
134     PrintTree(pRoot);
135     return 0;
136 }
时间: 2024-10-29 00:54:00

二叉树学习三:AVL树的相关文章

二叉树学习笔记之树的旋转

树旋转(Tree rotation)是二叉树中的一种子树调整操作,每一次旋转并不影响对该二叉树进行中序遍历的结果.树旋转通常应用于需要调整树的局部平衡性的场合. >>左旋和右旋 树的旋转有两种基本的操作,即左旋(逆时针方向旋转)和右旋(顺时针方向旋转). 树旋转包括两个不同的方式,分别是左旋转(以P为转轴)和右旋转(以Q为转轴).两种旋转呈镜像,而且互为逆操作. 下图示意了两种树旋转过程中, 子树的初态和终态 +---+ +---+ | Q | | P | +---+ +---+ / \ ri

小代码 向原文学习 对AVL树的4种情况 用字母标记整理

   /******************  环境:http://anycodes.cn/zh/  AVL  有高度标签    红黑树 更有颜色标记  http://blog.csdn.net/whucyl/article/details/17289841  我们总是以ABC 3个结点为例子 插入元素后C总是不平衡的  LL RR 较为简单   交换后C还是出于下方  LR RL 统一的一句就是  C总提出交换子树,要翻身做了老大.  LL LR与 RR RL是对称的4种情况写了前2种就能写出

判断一棵二叉树是否为AVL树

思路:AVL树是高度平衡的二叉搜索树,这里为了清晰说明,分别判断是否为搜索树,是否为平衡树. struct TreeNode { struct TreeNode *left; struct TreeNode *right; int key; }; //这里先判断是否为二叉搜索树,其次判断是否为平衡的 bool IsAVL(TreeNode *root,int depth) { if (isBST(root)&&isBalance(root,&depth)) return true;

数据结构与算法系列研究五——树、二叉树、三叉树、平衡排序二叉树AVL

树.二叉树.三叉树.平衡排序二叉树AVL 一.树的定义 树是计算机算法最重要的非线性结构.树中每个数据元素至多有一个直接前驱,但可以有多个直接后继.树是一种以分支关系定义的层次结构.    a.树是n(≥0)结点组成的有限集合.{N.沃恩}     (树是n(n≥1)个结点组成的有限集合.{D.E.Knuth})      在任意一棵非空树中:        ⑴有且仅有一个没有前驱的结点----根(root).        ⑵当n>1时,其余结点有且仅有一个直接前驱.         ⑶所有结

【算法导论学习-26】 二叉树专题4:红黑树、AVL树、B-Tree

1.   红黑树(Red-Black Trees) 参考<算法导论>P308页,红黑树是一种对树的高度要求最灵活的准平衡二叉搜索树.五大属性: 1: Every node is either RED or BLACK. 2: The root is black. 3: Every leaf(NIL) is black.  (The NIL is the sentinel.) 4: If a node is RED, then both its children areblack. 5: For

AVL树学习(平衡二叉树)

一.基本概念 AVL树既是平衡二叉树.AVL树的定义首先要求该树是二叉查找树(满足排序规则),并在此基础上增加了每个节点的平衡因子的定义,一个节点的平衡因子是该节点的左子树树高减去右子树树高的值. =========================================================================== 1. 二叉查找树:又称二叉排序树/二叉搜索树,具有以下性质: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值: (2)若右子树不空,则

python常用算法(5)——树,二叉树与AVL树

1,树 树是一种非常重要的非线性数据结构,直观的看,它是数据元素(在树中称为节点)按分支关系组织起来的结构,很像自然界中树那样.树结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都可用树形象表示.树在计算机领域中也得到了广泛应用,如在编译源程序时,可用树表示源程序的语法结构.又如在数据库系统中,树型结构也是信息的重要组织形式之一.一切具有层次关系的问题都可以用树来描述. 树(Tree)是元素的集合.树的定义是递归的,树是一种递归的数据结构.比如:目录结构.树是由n个结点组成的集合:如

二叉树、二叉搜索树、AVL树的java实现

数据结构一直都是断断续续的看,总是觉得理解的不够深入,特别是对树的理解,一直都很浅显,今儿又看了一遍,来做个总结吧. 首先,树中的一些概念: 1.树的节点包含一个数据元素,以及若干指向其子树的分支.节点拥有的子树的数量称为节点的度.节点的最大层次称为树的深度或高度. 2.二叉树是一种树形结构,其特点是每个节点至多有两棵子树,且子树有左右之分,次序不能随意颠倒. 3.满二叉树:一棵深度为k且有2^k - 1个节点的二叉树,称之为满二叉树. 4.完全二叉树:对一个深度为k,节点个数为n的二叉树,当且

数据结构学习笔记04树(二叉树、二叉搜索树、平衡二叉树)

一.树 树的基本术语 ①结点的度(Degree):结点的子树个数 ②树的度:树的所有结点中最大的度数 ③叶结点(Leaf):度为0的结点 ④父结点(Parent):有子树的结点是其子树的根结点的父结点 ⑤子结点(Child):若A结点是B结点的父结点,则称B结点是A结点的子结点:子结点也称孩子结点. ⑥兄弟结点(Sibling):具有同一父结点的各结点彼此是兄弟结点. ⑦路径和路径长度:从结点n1到nk的路径为一个结点序列n1 , n2 ,… , nk , ni是 ni+1的父结点.路径所包含边