1. 程式人生 > >圖解平衡二叉樹(AVL樹)程式碼實現

圖解平衡二叉樹(AVL樹)程式碼實現

一、平衡二叉樹的概念

對於二叉樹進行查詢的時間複雜度是由查詢過程中的比較次數來衡量的
比較是從根結點到葉節點的路徑進行的,取決於樹的深度樹深在最好的情況下是O(logN)
當二叉樹退化成一棵單枝樹的情況下,查詢的複雜度將是線性的O(N)

假定二叉搜尋樹中每個結點的查詢概率都是相同的,就稱查詢所有結點的比較次數的平均值為“平均查詢長度ASL
其中ASL = (∑深度k*該層的結點數)/總的結點數
一棵樹的ASL越小,它的結構越好,與完全二叉樹越接近,對它的查詢時間複雜度也越接近O(logN)

AVL樹的插入、刪除、查詢操作均可以在O(logN)時間內完成


要麼它是一棵空樹,如果它非空:
首先,它要是一棵二叉搜尋樹
其次,任一結點的左右子樹均為AVL樹
最後,某一結點的左右子樹之差的絕對值不超過1
平衡因子BF(T)= height(T->left) - height(T->right),AVL樹的平衡因子只能在{ 1, 0, -1 }取值


二、平衡二叉樹的調整

首先大家都知道要先定義一棵平衡二叉樹的結點結構
在這裡插入圖片描述

還有我們是這樣去獲得一棵樹的高度的
在這裡插入圖片描述

情況1:LL情況(破壞者在被破壞者左子樹的左子樹上)

在這裡插入圖片描述

情況2:RR情況(破壞者在被破壞者右子樹的右子樹上)

在這裡插入圖片描述

情況3:LR情況(破壞者在被破壞者左子樹的右子樹上)

在這裡插入圖片描述

情況4:RL情況(破壞者在被破壞者右子樹的左子樹上)

在這裡插入圖片描述


三、建立AVL樹

在這裡插入圖片描述
在這裡插入圖片描述


測試結果及程式碼

在這裡插入圖片描述
在這裡插入圖片描述

#include <stdio.h>
#include <malloc.h>
#include <iostream>
#include <stdlib.h> 

typedef int ElemType;
struct TreeNode {
	ElemType data;
int height; struct TreeNode *left; struct TreeNode *right; }; typedef TreeNode *AVLtree; int GetHeightOfTree(TreeNode *T) { if (T) { return GetHeightOfTree(T->left) > GetHeightOfTree(T->right) ? GetHeightOfTree(T->left) + 1 : GetHeightOfTree(T->right) + 1; } else { return 0; } } int Max(int a, int b) { return a > b ? a : b; } AVLtree LL_rotate(AVLtree T) { AVLtree L; L = T->right; T->left = L->right; L->right = T; T->height = Max(GetHeightOfTree(T->left), GetHeightOfTree(T->right)) + 1; L->height = Max(GetHeightOfTree(L->left), T->height) + 1; return L; } AVLtree RR_rotate(AVLtree T) { AVLtree R; R = T->right; T->right = R->left; R->left = T; T->height = Max(GetHeightOfTree(T->left), GetHeightOfTree(T->right)) + 1; R->height = Max(GetHeightOfTree(R->right), T->height) + 1; return R; } AVLtree LR_rotate(AVLtree T) { T->left = RR_rotate(T->left); // 以根結點T的左子樹的根結點作為根結點進去旋轉,返回的結點作為T的左子樹根結點 return LL_rotate(T); } AVLtree RL_rotate(AVLtree T) { T->right = LL_rotate(T->right); return RR_rotate(T); } AVLtree InsertAVL(AVLtree T, ElemType x) { if (T == NULL) { T = (AVLtree)malloc(sizeof(TreeNode)); T->data = x; T->left = T->right = NULL; T->height = 1; } else if (x < T->data) { T->left = InsertAVL(T->left, x); // 插入,注意返回值指向了新的結點為T的左子樹 if (GetHeightOfTree(T->left) - GetHeightOfTree(T->right) == 2) { if (x < T->left->data) { T = LL_rotate(T); } else if (x > T->left->data) { T = LR_rotate(T); } else { ; } } } else if (x > T->data) { T->right = InsertAVL(T->right, x); // 插入,注意返回值指向了新的結點為T的右子樹 if (GetHeightOfTree(T->left) - GetHeightOfTree(T->right) == -2) { if (x > T->right->data) { T = RR_rotate(T); } else if (x < T->right->data) { T = RL_rotate(T); } else { ; } } } else { ; } T->height = Max(GetHeightOfTree(T->left), GetHeightOfTree(T->right)) + 1; return T; } AVLtree CreateAVL(ElemType *a, int N) { AVLtree root = NULL; // 記得初始化為NULL for (int i = 0; i < N; ++i) { root = InsertAVL(root, a[i]); } return root; } void PreOrderTraversal(TreeNode *T) { if (T) { printf("%d ", T->data); PreOrderTraversal(T->left); PreOrderTraversal(T->right); } } void InOrderTraversal(TreeNode *T) { if (T) { InOrderTraversal(T->left); printf("%d ", T->data); InOrderTraversal(T->right); } } void PostOrderTraversal(TreeNode *T) { if (T) { PostOrderTraversal(T->left); PostOrderTraversal(T->right); printf("%d ", T->data); } } int main(int argc, char *argv[]) { ElemType arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; AVLtree t = CreateAVL(arr, 10); puts("先序遍歷: "); PreOrderTraversal(t); puts("\n"); puts("中序遍歷: "); InOrderTraversal(t); puts("\n"); puts("後序遍歷: "); PostOrderTraversal(t); puts("\n"); return 0; }