数据结构(三)实现AVL树

AVL树的定义
一种自平衡二叉查找树,中面向内存的数据结构。
二叉搜索树T为AVL树的满足条件为:

  • T是空树
  • T若不是空树,则TL、TR都是AVL树,且|HL-HR| <= 1 (节点的左子树高度与节点的右子树高度差的绝对值小于等于1)

说明

AVL树的实现类为AVLTree继承自前篇中的二叉搜索树BTreeSort ,AVL树的节点类为AVLNode继承自二叉树节点类BTreeNode。

实现代码

AVL树节点定义

public class AVLNode extends BTreeNode {
 
    public int height; // 树高
    public int balanceFactor; // 平衡因子
   
    public AVLNode(int key){
        super(key);
    }
}

AVL树实现类

public class AVLTree extends BTreeSort {
 
    private BTreeNode root;
 
    // 计算树高
    public int height(BTreeNode root) {
        if (null == root) {
            return 0;
        }
10          return ((AVLNode) root).height;
11      }
12   
13      // 计算平衡因子
14      public void UpdateBalanceFactor(BTreeNode root) {
15          if (null == root) {
16              return;
17          }
18          int left = height(root.left);
19          int right = height(root.right);
20          ((AVLNode) root).height = Math.max(left, right) + 1;
21          ((AVLNode) root).balanceFactor = left - right;
22      }
23   
24      // 左左类型 -- 右转
25      public BTreeNode rotateRight(BTreeNode root) {
26          if (null == root) {
27              return root;
28          }
29          BTreeNode node = root.left;
30          root.left = node.right;
31          node.right = root;
32          UpdateBalanceFactor(root);
33          UpdateBalanceFactor(node);
34          return node;
35      }
36   
37      // 右右类型 -- 左转
38      public BTreeNode rotateLeft(BTreeNode root) {
39          if (null == root) {
40              return root;
41          }
42          BTreeNode node = root.right;
43          root.right = node.left;
44          node.left = root;
45          UpdateBalanceFactor(root);
46          UpdateBalanceFactor(node);
47          return node;
48      }
49   
50      // 左右类型
51      public BTreeNode rotateLeftRight(BTreeNode root) {
52          if (null == root) {
53              return root;
54          }
55          root.left = rotateLeft(root.left);
56          return rotateRight(root);
57      }
58   
59      // 右左类型
60      public BTreeNode rotateRightLeft(BTreeNode root) {
61          if (null == root) {
62              return root;
63          }
64          root.right = rotateRight(root.right);
65          return rotateLeft(root);
66      }
67   
68      // 插入节点
69      public void insert(int key) {
70          if (null == root) {
71              root = new AVLNode(key);
72              return;
73          }
74          root = insert(root, key);
75      }
76   
77      // 插入节点构造AVL树
78      public BTreeNode insert(BTreeNode root, int key) {
79          if (null == root) {
80              root = new AVLNode(key);
81              UpdateBalanceFactor(root);
82              return root;
83          }
84          // 等于
85          if (key == root.key) {
86              return root;
87          }
88          // 大于 -- 向左
89          if (root.key > key) {
90              root.left = insert(root.left, key);
91              UpdateBalanceFactor(root);
92              // / - 左
93              if (((AVLNode) root).balanceFactor > 1) {
94                  // / - 左
95                  if (((AVLNode) root.left).balanceFactor > 0) {
96                      root = rotateRight(root);
97                  } else {
98                      root = rotateLeftRight(root);
99                  }
100              }
101          }
102          // 小于或等于 -- 向右
103          else {
104              root.right = insert(root.right, key);
105              UpdateBalanceFactor(root);
106              // / - 右
107              if (((AVLNode) root).balanceFactor < -1) {
108                  // / - 右
109                  if (((AVLNode) root.right).balanceFactor < 0) {
110                      root = rotateLeft(root);
111                  } else {
112                      root = rotateRightLeft(root);
113                  }
114              }
115          }
116          UpdateBalanceFactor(root);
117          return root;
118      }
119   
120      // 删除节点
121      public BTreeNode delete(BTreeNode root, int key) {
122          if (null == root) {
123              return root;
124          }
125          // 找到需删除的节点
126          if (root.key == key) {
127              // 该节点左右子树都不空处理
128              if (null != root.left && null != root.right) {
129                  // 左边子树高度大于右子树高度,使用左子树中最大节点替换需要删除的节点
130                  if (((AVLNode) root.left).height > ((AVLNode) root.right).height) {
131                      BTreeNode node = max(root.left);
132                      root.key = node.key;
133                      root.left = delete(root.left,node.key);
134                  } else {
135                      // 使用右子树中最小节点替换需要删除的节点
136                      BTreeNode node = min(root.right);
137                      root.key = node.key;
138                      root.left = delete(root.right,node.key);
139                  }
140              } else {
141                  root = null != root.left ? root.left : root.right;
142              }
143              UpdateBalanceFactor(root);
144              return root;
145          }
146          // 往左边查找删除节点
147          else if (root.key > key) {
148              root.left = delete(root.left, key);
149              UpdateBalanceFactor(root);
150              // 左子树变矮只有可能右子树高度大于等于左子树高度
151              // \
152              if (((AVLNode)root).balanceFactor < -1){
153                  // \ 右右类型处理
154                  if (((AVLNode)root.left).balanceFactor < 0){
155                      root = rotateLeft(root);
156                  }
157                  else{
158                      // 右左类型处理
159                      root = rotateRightLeft(root);
160                  }
161              }
162          }
163          // 往右边查找删除节点
164          else {
165              root.right = delete(root.right, key);
166              UpdateBalanceFactor(root);
167              // 右子树变矮只有可能左子树高度大于等于右子树高度
168              // /
169              if (((AVLNode)root).balanceFactor > 1){
170                  // / 左左类型
171                  if (((AVLNode)root.left).balanceFactor > 0){
172                      root = rotateRight(root);
173                  }
174                  else{
175                      // 左右类型
176                      root = rotateLeftRight(root);
177                  }
178              }
179          }
180          UpdateBalanceFactor(root);
181          return root;
182      }
183     
184      // 中顺遍历
185      public void midTraversal(){
186          this.midTraversal(root);
187      }
188     
189      // 删除节点
190      public void delete(int key) {
191          this.delete(root, key);
192      }
193     
194      public static void main(String[] args) {
195          Integer[] nums = new Integer[] { 2012911171918253023,
196                  5535678113 };
197          System.out.println(Arrays.asList(nums));
198          AVLTree avlTree = new AVLTree();
199          for (Integer num:nums){
200              avlTree.insert(num.intValue());
201          }
202          avlTree.delete(20);
203          System.out.print("中序遍历:");
204          avlTree.midTraversal();
205          System.out.println();
206      }
207  }
时间: 2024-12-07 11:04:22

数据结构(三)实现AVL树的相关文章

数据结构与算法分析-AVL树深入探讨

.title { text-align: center; margin-bottom: .2em } .subtitle { text-align: center; font-size: medium; font-weight: bold; margin-top: 0 } .todo { font-family: monospace; color: red } .done { font-family: monospace; color: green } .priority { font-fami

数据结构-平衡二叉树(AVL树)

一.平衡二叉树的定义 使树的高度在每次插入元素后仍然能保持O(logn)的级别 AVL仍然是一棵二叉查找树 左右子树的高度之差是平衡因子,且值不超过1 //数据类型 struct node{ int v, height; node *lchild, *rchild; }; //新建一个结点 node* newNode(int v){ node* Node = new node; Node->v = v; Node->height = 1; Node->lchild = Node->

My集合框架第三弹 AVL树

旋转操作: 由于任意一个结点最多只有两个儿子,所以当高度不平衡时,只可能是以下四种情况造成的: 1. 对该结点的左儿子的左子树进行了一次插入. 2. 对该结点的左儿子的右子树进行了一次插入. 3. 对该结点的右儿子的左子树进行了一次插入. 4. 对该结点的右儿子的右子树进行了一次插入. 向AVL树插入节点后,需要让AVL树重新平衡 step1:从插入节点向根节点溯源,观察是否存在不平衡节点(左右子树高度差),    if(不存在),return    else  step2step2:标记不平衡

二叉树学习三: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型:在不平衡的儿结点先进行右旋转,然后进

[数据结构与算法] : AVL树

头文件 1 typedef int ElementType; 2 3 #ifndef _AVLTREE_H_ 4 #define _AVLTREE_H_ 5 6 struct AvlNode; 7 typedef struct AvlNode *Position; 8 typedef struct AvlNode *AvlTree; 9 10 AvlTree MakeEmpty(AvlTree T); 11 Position Find(ElementType X, AvlTree T); 12

平衡二叉搜索树(AVL树,红黑树)数据结构和区别

平衡二叉搜索树(Balanced Binary Search Tree) 经典常见的自平衡的二叉搜索树(Self-balancing Binary Search Tree)有 ① AVL树 :Windows NT 内核中广泛使用 ② 红黑树:C++ STL(比如 map.set )Java 的 TreeMap.TreeSet.HashMap.HashSet  Linux 的进程调度  Ngix 的 timer 管理 1 AVL树  vs  红黑树 ①AVL树 平衡标准比较严格:每个左右子树的高度

平衡二叉搜索树(AVL树)的原理及实现源代码(有图文详解和C++、Java实现代码)

一.AVL树(平衡二叉搜索树)是什么? AVL树是根据它的发明者G.M. Adelson-Velsky和E.M. Landis命名的.AVL树本质上还是一棵二叉搜索树,它的特点是: 1.本身首先是一棵二叉搜索树. 2.带有平衡条件:每个非叶子结点的左右子树的高度之差的绝对值(平衡因子)最多为1. 例如: 5             5 / \            /  \ 2   6         2   6 / \    \         / \ 1  4   7       1  4

AVL树插入和删除

一.AVL树简介 AVL树是一种平衡的二叉查找树. 平衡二叉树(AVL 树)是一棵空树,或者是具有下列性质的二叉排序树:    1它的左子树和右子树都是平衡二叉树,    2且左子树和右子树高度之差的绝对值不超过 1. 定义平衡因子(BF)为该结点左子树的高度减去右子树的高度所得的高度差:AVL 树任一结点平衡因子只能取-1,0,1: 二.AVL树插入 插入:先查找被插入元素,如果存在,则不操作:如果不存在,则插入. 插入后就是调整和选择的问题. 我们先看一下我们会面临怎么样的问题: 离插入点最

AVL树学习(平衡二叉树)

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