1. 程式人生 > 實用技巧 >平衡二叉樹詳解

平衡二叉樹詳解

平衡二叉樹詳解

簡介

平衡二叉樹(Balanced Binary Tree)具有以下性質:它是一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,並且左右兩個子樹都是一棵平衡二叉樹。平衡二叉樹的常用實現方法有紅黑樹、AVL、替罪羊樹、Treap、伸展樹等。 其中最為經典當屬AVL樹,我們

總計而言就是:平衡二叉樹是一種二叉排序樹,其中每一個結點的左子樹和右子樹的高度差至多等於1。

性值

AVL樹具有下列性質的二叉樹(注意,空樹也屬於一種平衡二叉樹):

l 它必須是一顆二叉查詢樹

l 它的左子樹和右子樹都是平衡二叉樹,且左子樹和右子樹的深度之差的絕對值不超過1。

l 若將二叉樹節點的平衡因子BF定義為該節點的左子樹的深度減去它的右子樹的深度,則平衡二叉樹上所有節點的平衡因子只可能為-1,0,1.

l 只要二叉樹上有一個節點的平衡因子的絕對值大於1,那麼這顆平衡二叉樹就失去了平衡。

實現

平衡二叉樹不平衡的情形:

把需要重新平衡的結點叫做α,由於任意兩個結點最多隻有兩個兒子,因此高度不平衡時,α結點的兩顆子樹的高度相差2.容易看出,這種不平衡可能出現在下面4中情況中:

1.對α的左兒子的左子樹進行一次插入

2.對α的左兒子的右子樹進行一次插入

3.對α的右兒子的左子樹進行一次插入

4.對α的右兒子的右子樹進行一次插入

(1)LR型

(2)LL型

(3)RR型

(4)RL型

完整程式碼

#include<stdio.h>
#include
<stdlib.h> //結點設計 typedef struct Node { int key; struct Node *left; struct Node *right; int height; } BTNode; int height(struct Node *N) { if (N == NULL) return 0; return N->height; } int max(int a, int b) { return (a > b) ? a : b; } BTNode* newNode(int
key) { struct Node* node = (BTNode*)malloc(sizeof(struct Node)); node->key = key; node->left = NULL; node->right = NULL; node->height = 1; return(node); } //ll型調整 BTNode* ll_rotate(BTNode* y) { BTNode *x = y->left; y->left = x->right; x->right = y; y->height = max(height(y->left), height(y->right)) + 1; x->height = max(height(x->left), height(x->right)) + 1; return x; } //rr型調整 BTNode* rr_rotate(BTNode* y) { BTNode *x = y->right; y->right = x->left; x->left = y; y->height = max(height(y->left), height(y->right)) + 1; x->height = max(height(x->left), height(x->right)) + 1; return x; } //判斷平衡 int getBalance(BTNode* N) { if (N == NULL) return 0; return height(N->left) - height(N->right); } //插入結點&資料 BTNode* insert(BTNode* node, int key) { if (node == NULL) return newNode(key); if (key < node->key) node->left = insert(node->left, key); else if (key > node->key) node->right = insert(node->right, key); else return node; node->height = 1 + max(height(node->left), height(node->right)); int balance = getBalance(node); if (balance > 1 && key < node->left->key) //LL型 return ll_rotate(node); if (balance < -1 && key > node->right->key) //RR型 return rr_rotate(node); if (balance > 1 && key > node->left->key) { //LR型 node->left = rr_rotate(node->left); return ll_rotate(node); } if (balance < -1 && key < node->right->key) { //RL型 node->right = ll_rotate(node->right); return rr_rotate(node); } return node; } //遍歷 void preOrder(struct Node *root) { if (root != NULL) { printf("%d ", root->key); preOrder(root->left); preOrder(root->right); } } int main() { BTNode *root = NULL; root = insert(root, 2); root = insert(root, 1); root = insert(root, 0); root = insert(root, 3); root = insert(root, 4); root = insert(root, 4); root = insert(root, 5); root = insert(root, 6); root = insert(root, 9); root = insert(root, 8); root = insert(root, 7); printf("前序遍歷:"); preOrder(root); return 0; }