平衡二叉树
定义:
平衡二叉搜索树(Self-balancing binary search tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。平衡二叉树的常用实现方法有红黑树、AVL、替罪羊树、Treap、伸展树等。 最小二叉平衡树的节点总数的公式如下 F(n)=F(n-1)+F(n-2)+1 这个类似于一个递归的数列,可以参考Fibonacci(斐波那契)数列,1是根节点,F(n-1)是左子树的节点数量,F(n-2)是右子树的节点数量。
其中最艰难的是插入和删除,这里提供两种方法。
测试函数:
#include <stdio.h>
#include <stdlib.h>
#include "avltree.h"
void show_menu(void){
printf("*******平衡二叉排序(AVL树功能测试**********\n");
printf("**1. 插入元素 \n");
printf("**2. 删除元素 \n");
// printf("**3. 查找某元素是否在树中 \n");
printf("**4. 树是否为空 \n");
printf("**5. 树中元素个数 \n");
printf("**6. 树的高度 \n");
printf("**7. 树的先序遍历 \n");
printf("**8. 树的中序遍历 \n");
printf("**9. 树的后序遍历 \n");
// printf("**10.树的层序遍历 \n");
printf("**11. 清空树 \n");
printf("**0. 退出 \n");
printf(">>>>");
}
void travel(int n){
printf("%d ",n);
}
void test_bin_tree(void){
AVLTree tree = NULL;
avl_tree_init(&tree);
while(true){
show_menu();
int opt = 0;
int elem = 0;
int ret = 0;
bool f = true;
scanf("%d",&opt);
switch(opt){
case 1:
printf("请输入要插入二叉排序树中的元素:");
scanf("%d",&elem);
ret = avl_tree_insert(&tree,elem);
if(ret == 0){
printf("插入成功!\n");
}else{
if(ret == -1){
printf("树中已有该元素,插入失败!\n");
}else{
printf("插入失败!内存问题!\n");
}
}
break;
case 2:
printf("请输入要删除的元素:");
scanf("%d",&elem);
ret = avl_tree_delete(&tree,elem);
if(ret == 0){
printf("删除成功!\n");
}else{
printf("删除失败!树中没有该元素!\n");
}
break;
case 3:
// printf("请输入要查找树中是否存在的元素:");
// scanf("%d",&elem);
// if(val_tree_contains(tree,elem)){
// printf("树中存在该元素!\n");
// }else{
// printf("树中没有该元素!\n");
// }
break;
case 4:
avl_tree_empty(tree)?puts("空空如也!\n"):puts("树中有元素!\n");
case 5:
printf("树中元素个数:%u\n",avl_tree_size(tree));
case 6:
printf("树的高度为:%u\n",avl_tree_hight(tree));
break;
case 7:
avl_tree_front_travel(tree,travel);
printf("\n");
case 8:
avl_tree_mid_travel(tree,travel);
printf("\n");
case 9:
avl_tree_back_travel(tree,travel);
printf("\n");
case 10:
//avl_tree_layer_travel(tree,travel);
printf("\n");
break;
case 11:
avl_tree_clear(&tree);
break;
case 0:
avl_tree_destroy(&tree);
return;
}
}
}
int main(int argc, char *argv[]) {
test_bin_tree();
return 0;
}
方法一:非栈的形式
#include "avltree.h"
/*
typedef int ETYPE;
typedef struct AVLNode{
ETYPE elem;
struct AVLNode *lchild,*rchild;
size_t hight; //结点所在高度
//int balance; //平衡因子
}AVLNode,*AVLTree;
*/
#define HIGHT(node) (node==NULL?0:node->hight)
#define REHIGHT(node) (HIGHT(node->lchild)>HIGHT(node->rchild)?HIGHT(node->lchild)+1:HIGHT(node->rchild)+1)
void avl_tree_init(AVLTree *proot){
*proot = NULL;
}
bool avl_tree_empty(AVLTree root){
return root == NULL;
}
size_t avl_tree_size(AVLTree root){
if(root==NULL)
return 0;
return 1+avl_tree_size(root->lchild)+avl_tree_size(root->rchild);
}
size_t avl_tree_hight(AVLTree root){
return root==NULL?0:root->hight;
}
static struct AVLNode *avl_tree_create_node(ETYPE elem){
struct AVLNode *node = malloc(sizeof(struct AVLNode));
if(node!=NULL){
node->elem = elem;
node->lchild = NULL;
node->rchild = NULL;
node->hight = 1;
}
return node;
}
/*
| |
node left
/ \ / \
left right -->node进行右旋 ll node
/ \ / \
ll lr lr right
*/
static struct AVLNode *LL_rotation(struct AVLNode *node){
struct AVLNode *left = node->lchild;
node->lchild = left->rchild;
left->rchild = node;
node->hight = REHIGHT(node);
left->hight = REHIGHT(left);
return left;
}
/*
| |
node right
/ \ / \
left right 左旋 node rr
/ \ / \
rl rr left rl
*/
static struct AVLNode *RR_rotation(struct AVLNode *node){
struct AVLNode *right = node->rchild;
node->rchild = right->lchild;
right->lchild = node;
node->hight = REHIGHT(node);
right->hight = REHIGHT(right);
return right;
}
/*
|
node
/ \
left right
/ \
ll lr
*/
static struct AVLNode *LR_rotation(struct AVLNode *node){
node->lchild = RR_rotation(node->lchild);
return LL_rotation(node);
}
/*
|
node
/ \
left right
/ \
rl rr
*/
static struct AVLNode *RL_rotation(struct AVLNode *node){
node->rchild = LL_rotation(node->rchild);
return RR_rotation(node);
}
static void avl_tree_inset_repair(AVLTree *proot){
struct AVLNode *node = *proot;
int bn = HIGHT(node->lchild) - HIGHT(node->rchild);
if(bn==2){//左高
int lbn = HIGHT(node->lchild->lchild) - HIGHT(node->lchild->rchild);
if(lbn==1){
*proot = LL_rotation(node);//对node结点进行右旋 LL
}else{//lbn==-1
*proot = LR_rotation(node);//LR
}
}else if(bn==-2){//右高
int rbn = HIGHT(node->rchild->lchild) - HIGHT(node->rchild->rchild);
if(rbn==-1){
*proot = RR_rotation(node);//RR
}else{
*proot = RL_rotation(node);//RL
}
}
}
int avl_tree_insert(AVLTree *proot,ETYPE elem){
//先把结点插入进去 如果失去平衡进行调整(旋转) 递归形式
if(*proot == NULL){
*proot = avl_tree_create_node(elem);
if(*proot == NULL){
return -2;
}
return 0;
}
int ret = 0;
if(elem < (*proot)->elem){
ret = avl_tree_insert(&(*proot)->lchild,elem);
}else if(elem > (*proot)->elem){
ret = avl_tree_insert(&(*proot)->rchild,elem);
}else{
return -1;
}
if(ret == 0){//插入成功 可能失衡 需要调整
avl_tree_inset_repair(proot);
(*proot)->hight = REHIGHT((*proot));
}
return ret;
}
int avl_tree_delete(AVLTree *proot,ETYPE elem){
if(*proot == NULL)
{
return -1;
}
int ret = 0;
if(elem = (*proot)->elem)
{
struct AVLNode *node = *proot;
if(node->lchild != NULL && node->rchild != NULL)
{
for(node = node->lchild;node->rchild!=NULL;node = node->rchild);
(*proot)->elem = node->elem;
//去删除右子树中的最大值
ret = avl_tree_delete(&(*proot)->lchild,node->elem);//必须用递归调用删除
}
else
{
*proot = node->lchild!=NULL?node->lchild:node->rchild;
free(node);
return 0;
}
}
if(elem < (*proot)->elem)
{
ret = avl_tree_delete(&(*proot)->lchild,elem);
}
else
{
ret = avl_tree_delete(&(*proot)->rchild,elem);
}
if(ret == 0)
{
avl_tree_inset_repair(proot);
(*proot)->hight = REHIGHT((*proot));
}
}
void avl_tree_front_travel(AVLTree root,void (*travel)(ETYPE)){
if(root!=NULL){
travel(root->elem);
avl_tree_front_travel(root->lchild,travel);
avl_tree_front_travel(root->rchild,travel);
}
}
void avl_tree_mid_travel(AVLTree root,void (*travel)(ETYPE)){
if(root!=NULL){
avl_tree_mid_travel(root->lchild,travel);
travel(root->elem);
avl_tree_mid_travel(root->rchild,travel);
}
}
void avl_tree_back_travel(AVLTree root,void (*travel)(ETYPE)){
if(root!=NULL){
avl_tree_back_travel(root->lchild,travel);
avl_tree_back_travel(root->rchild,travel);
travel(root->elem);
}
}
void avl_tree_clear(AVLTree *proot){
if(*proot!=NULL){
avl_tree_clear(&(*proot)->lchild);
avl_tree_clear(&(*proot)->rchild);
free(*proot);
*proot = NULL;
}
}
void avl_tree_destroy(AVLTree *proot){
avl_tree_clear(proot);
}
方法二:栈实现
首先给出定义一个栈
#include "stack.h"
/*
typedef struct AVLNode ** ET;
typedef struct Stack{
ET *data;
size_t cap;
size_t size;
}Stack;
*/
int stack_init(Stack *ps,size_t cap){
ps->data = malloc(sizeof(ET)*cap);
if(ps->data == NULL){
return -1;
}
ps->cap = cap;
ps->size = 0;
}
bool stack_empty(Stack *ps){
return ps->size == 0;
}
bool stack_full(Stack *ps){
return ps->size == ps->cap;
}
int stack_push(Stack *ps,ET data){
if(stack_full(ps))
return -1;
ps->data[ps->size++] = data;
return 0;
}
ET stack_pop(Stack *ps){//给自己用,栈空时自己不用调用
return ps->data[--ps->size];
}
void stack_destroy(Stack *ps){
free(ps->data);
}
栈实现代码
#include "avltree.h"
#include "stack.h"
/*
typedef int ETYPE;
typedef struct AVLNode{
ETYPE elem;
int hight;
struct AVLNode *lchild;
struct AVLNode *rchild;
}AVLNode,*AVLTree;
*/
//插入的结点作为叶子结点
static struct AVLNode *avl_tree_create_node(ETYPE elem){
struct AVLNode *node = (struct AVLNode *)malloc(sizeof(struct AVLNode));
if(node!=NULL){
node->elem = elem;
node->hight = 1;
node->lchild = NULL;
node->rchild = NULL;
}
return node;
}
#define HIGHT(node) (node==NULL?0:node->hight)
#define REHIGHT(node) (HIGHT(node->lchild)>HIGHT(node->rchild)?HIGHT(node->lchild)+1:HIGHT(node->rchild)+1)
enum BALANCE{LL=2,RR=-2};
/*
| |
node left
/ \ node结点进行右旋 / \
left right ll node
/ \ / \
ll lr lr right
*/
static struct AVLNode *LL_rotate(AVLNode *node){
struct AVLNode *left = node->lchild;
node->lchild = left->rchild;
left->rchild = node;
node->hight = REHIGHT(node);
left->hight = REHIGHT(left);
return left;
}
/*
| |
node right
/ \ node结点进行左旋 / \
left right node rr
/ \ / \
rl rr left rl
*/
static struct AVLNode *RR_rotate(AVLNode *node){
struct AVLNode *right = node->rchild;
node->rchild = right->lchild;
right->lchild = node;
node->hight = REHIGHT(node);
right->hight = REHIGHT(right);
return right;
}
/*
| | |
node node lr
/ \ / \ / \
left right --left左旋 lr right node进行右旋 left node
/ \ / / \
ll lr left ll right
/
ll
*/
static struct AVLNode *LR_rotate(AVLNode *node){
node->lchild = RR_rotate(node->lchild);
return LL_rotate(node);
}
/*
| | |
node node rl
/ \ / \ / \
left right --right右旋 left rl node进行左旋 node right
/ \ \ / \
rl rr right left rr
\
rr
*/
static struct AVLNode *RL_rotate(AVLNode *node){
node->rchild = LL_rotate(node->rchild);
return RR_rotate(node);
}
static void avl_tree_repair(AVLTree *proot){
int lh = HIGHT((*proot)->lchild);
int rh = HIGHT((*proot)->rchild);
if(lh-rh==LL){
struct AVLNode *left = (*proot)->lchild;
int llh = HIGHT(left->lchild);
int lrh = HIGHT(left->rchild);
if(llh>=lrh){//LL
*proot = LL_rotate(*proot);
}else{//LR
*proot = LR_rotate(*proot);
}
}else if(lh-rh==RR){
struct AVLNode *right = (*proot)->rchild;
int rlh = HIGHT(right->lchild);
int rrh = HIGHT(right->rchild);
if(rlh>rrh){//RL
*proot = RL_rotate(*proot);
}else{//RR
*proot = RR_rotate(*proot);
}
}
}
int avl_tree_insert(AVLTree *proot,ETYPE elem){
Stack s;
stack_init(&s,avl_tree_size(*proot)+1);
while(*proot != NULL){
stack_push(&s,proot);
if(elem < (*proot)->elem){
proot = &(*proot)->lchild;
}else if(elem > (*proot)->elem){
proot = &(*proot)->rchild;
}else{
stack_destroy(&s);
return -1;
}
}
*proot = avl_tree_create_node(elem);
if(*proot == NULL){
stack_destroy(&s);
return -2;
}
while(!stack_empty(&s)){
proot = stack_pop(&s);
avl_tree_repair(proot);
(*proot)->hight = REHIGHT((*proot));
}
stack_destroy(&s);
return 0;
}
/*
int avl_tree_insert(AVLTree *proot,ETYPE elem){
//用栈保存比较的每一个结点 插入成功之后 取出栈中所有结点 依次调整高度 如果失衡进行调整
if(*proot == NULL){
*proot = avl_tree_create_node(elem);
if(*proot == NULL){
return -2;//申请内存失败
}
return 0;//插入成功 return *proot == NULL ? -2 : 0;
}
int ret = 0;
if(elem < (*proot)->elem){
ret = avl_tree_insert(&(*proot)->lchild,elem);
}else if(elem > (*proot)->elem){
ret = avl_tree_insert(&(*proot)->rchild,elem);
}else{
return -1;//插入相同的元素 直接失败
}
if(ret == 0){//插入成功 修复平衡 调整高度
avl_tree_repair(proot);
(*proot)->hight = REHIGHT((*proot));
}
return ret;
}
*/
int avl_tree_delete(AVLTree *proot,ETYPE elem){
Stack s;
stack_init(&s,avl_tree_size(*proot)+1);
while(*proot != NULL){
if(elem == (*proot)->elem){
break;
}else if(elem < (*proot)->elem){
proot = &(*proot)->lchild;
}else{
proot = &(*proot)->rchild;
}
stack_push(&s,proot);
}
if(*proot == NULL){
stack_destroy(&s);
return -1;
}
struct AVLNode *node = *proot;
if(node->lchild!=NULL && node->rchild!=NULL){
//struct AVLNode *left = node->lchild;
for(proot = &(*proot)->lchild; (*proot)->rchild!=NULL;proot = &(*proot)->rchild){
stack_push(&s,proot);
}
stack_pop(&s);//*proot == NULL
node->elem = (*proot)->elem;
node = *proot;
}
*proot = node->lchild!=NULL?node->lchild:node->rchild;
free(node);
while(!stack_empty(&s)){
proot = stack_pop(&s);
avl_tree_repair(proot);
(*proot)->hight = REHIGHT((*proot));
}
stack_destroy(&s);
return 0;
}
/*
int avl_tree_delete(AVLTree *proot,ETYPE elem){
if(*proot == NULL){
return -1;
}
int ret = 0;
if(elem == (*proot)->elem){
struct AVLNode *node = *proot;
if(node->lchild!=NULL && node->rchild!=NULL){
for(node = node->lchild;node->rchild!=NULL;node=node->rchild);
(*proot)->elem = node->elem;
//去删除右子树中的最大值
ret = avl_tree_delete(&(*proot)->lchild,node->elem);//必须用递归调用去删除
}else{
*proot = node->lchild!=NULL?node->lchild:node->rchild;
free(node);
return 0;
}
}
if(elem < (*proot)->elem){
ret = avl_tree_delete(&(*proot)->lchild,elem);
}else{
ret = avl_tree_delete(&(*proot)->rchild,elem);
}
if(ret == 0){
avl_tree_repair(proot);
(*proot)->hight = REHIGHT((*proot));
}
return ret;
}
*/
void avl_tree_init(AVLTree *proot){
*proot = NULL;
}
bool avl_tree_empty(AVLTree root){
return root == NULL;
}
size_t avl_tree_size(AVLTree root){
if(root==NULL)
return 0;
return 1+avl_tree_size(root->lchild)+avl_tree_size(root->rchild);
}
size_t avl_tree_hight(AVLTree root){
return root==NULL?0:root->hight;
}
void avl_tree_front_travel(AVLTree root,void (*travel)(ETYPE)){
if(root!=NULL){
travel(root->elem);
avl_tree_front_travel(root->lchild,travel);
avl_tree_front_travel(root->rchild,travel);
}
}
void avl_tree_mid_travel(AVLTree root,void (*travel)(ETYPE)){
if(root!=NULL){
avl_tree_mid_travel(root->lchild,travel);
travel(root->elem);
avl_tree_mid_travel(root->rchild,travel);
}
}
void avl_tree_back_travel(AVLTree root,void (*travel)(ETYPE)){
if(root!=NULL){
avl_tree_back_travel(root->lchild,travel);
avl_tree_back_travel(root->rchild,travel);
travel(root->elem);
}
}
void avl_tree_clear(AVLTree *proot){
if(*proot!=NULL){
avl_tree_clear(&(*proot)->lchild);
avl_tree_clear(&(*proot)->rchild);
free(*proot);
*proot = NULL;
}
}
void avl_tree_destroy(AVLTree *proot){
avl_tree_clear(proot);
}