一、定义:
平衡二叉树(Balanced Binary Tree),又叫AVL树。当非空树时,任一节点左右子树高度差绝对值不大于1,这种树叫做平衡二叉树。
平衡因子:左右子树的高度差叫做这棵树的平衡因子BF(Balance Factor).BF(T)=hl-hr,其中hl和hr分别是树T的左右子树高度。
二、性质:
它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。常用算法有红黑树、AVL、Treap、伸展树等。在平衡二叉搜索树中,我们可以看到,其高度一般都良好地维持在O(log(n)),大大降低了操作的时间复杂度。
三、操作:
AVL *creat();建树
Elementtype find();查找
void insert();插入
Elementtype del();删除
四、代码:
头文件:
#ifndef AVLTREE_H
#define AVLTREE_H
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct tree_node AVLT;
typedef int Elementtype;
struct tree_node{
Elementtype value;
AVLT *left;
AVLT *right;
int bf;
};
typedef struct stack_node STNode;
typedef AVLT* Element;
struct stack_node{
Element value;
STNode *next;
};
typedef struct {
STNode *top;
STNode *bottom;
}Stack;
#endif
AVLT *creatNode(Elementtype value); //生成新结点
AVLT *insertAVL1(AVLT *pTr,Elementtype value); //递归插入
AVLT *insertAVL2(AVLT *pTr,Elementtype value); //非递归插入
AVLT *delAVL1(AVLT *pTr,Elementtype value); //递归删除
AVLT *delAVL2(AVLT *pTr,Elementtype value); //非递归删除
void cleanAVL(AVLT **pTr); //清空树
void Preordertraversal(AVLT *pTr); //前序递归遍历
void Inordertraversal(AVLT *pTr); //中序递归遍历
void Postordertraversal(AVLT *pTr); //后续递归遍历
int getHAVL(AVLT *pTr); //求树高
int getBalance(AVLT *pTr); //求平衡因子
int max(int a,int b); //取大值
Elementtype maxNode(AVLT *pTr); //取左子树的最大值
Elementtype minNode(AVLT *pTr); //取右子树的最小值
AVLT *rotation(AVLT *pTr); //旋转封装
AVLT *ll(AVLT *pTr); //左左旋转
AVLT *rr(AVLT *pTr); //右右旋转
AVLT *lr(AVLT *pTr); //左右旋转
AVLT *rl(AVLT *pTr); //右左旋转
Stack *creatStack();
int isemptyStack(Stack *pStack);
void pushStack(Stack *pStack,Element value);
Element popStack(Stack *pStack);
void cleanStack(Stack **pStack);
函数实现:
#include "avltree.h"
AVLT *creatNode(Elementtype value){ //生成新结点
AVLT *pNode=(AVLT*)malloc(sizeof(AVLT));
pNode->value=value;
pNode->left=pNode->right=NULL;
pNode->bf=0;
return pNode;
}
AVLT *insertAVL1(AVLT *pTr,Elementtype value){ //递归插入
if(!pTr){
pTr=creatNode(value);
}else{
if(value<pTr->value){
pTr->left=insertAVL1(pTr->left,value);
pTr=rotation(pTr);
}else if(value>pTr->value){
pTr->right=insertAVL1(pTr->right,value);
pTr=rotation(pTr);
}
}
return pTr;
}
AVLT *insertAVL2(AVLT *pTr,Elementtype value){ //非递归插入
AVLT *pNode=creatNode(value);
AVLT *parent=NULL,*gparent=parent;
AVLT *ptemp=pTr;
Stack *pStack=creatStack();
if(ptemp){
while(ptemp){
parent=ptemp;
pushStack(pStack,parent);
if(value>ptemp->value){
ptemp=ptemp->right;
if(!ptemp){
parent->right=pNode;
}
}else if(value<ptemp->value){
ptemp=ptemp->left;
if(!ptemp){
parent->left=pNode;
}
}
}
}else{
pTr=pNode;
}
while(!isemptyStack(pStack)){
parent=popStack(pStack);
parent->bf=getBalance(parent);
if(parent->bf==2||parent->bf==-2){
parent=rotation(parent);
}
if(!isemptyStack(pStack)&&parent->value>pStack->top->value->value){
pStack->top->value->right=parent;
}else if(!isemptyStack(pStack)&&parent->value<pStack->top->value->value){
pStack->top->value->left=parent;
}else{
pTr=parent;
}
}
cleanStack(&pStack);
return pTr;
}
AVLT *delAVL1(AVLT *pTr,Elementtype value){ //递归删除
if(pTr){
if(value<pTr->value){
pTr->left=delAVL1(pTr->left,value);
pTr=rotation(pTr);
}else if(value>pTr->value){
pTr->right=delAVL1(pTr->right,value);
pTr=rotation(pTr);
}else{
if(pTr->left&&pTr->right){
Elementtype tempvalue=maxNode(pTr);
pTr->value=tempvalue;
pTr->left=delAVL1(pTr->left,tempvalue);
pTr=rotation(pTr);
}else if(!pTr->left){
pTr=pTr->right;
}else if(!pTr->right){
pTr=pTr->left;
}
}
}else{
printf("空树!\n");
}
return pTr;
}
AVLT *delAVL2(AVLT *pTr,Elementtype value){ //非递归删除
AVLT *ptemp=pTr,*parent=ptemp;
Stack *pStack=creatStack();
while(ptemp){
pushStack(pStack,ptemp);
if(value<ptemp->value){
ptemp=ptemp->left;
}else if(value>ptemp->value){
ptemp=ptemp->right;
}else{
ptemp=popStack(pStack);
if(!isemptyStack(pStack)&&!ptemp->left){
if(ptemp->value>pStack->top->value->value){
pStack->top->value->right=ptemp->right;
}else if(ptemp->value<pStack->top->value->value){
pStack->top->value->left=ptemp->right;
}
free(ptemp);ptemp=NULL;
}else if(!isemptyStack(pStack)&&!ptemp->right){
if(ptemp->value>pStack->top->value->value){
pStack->top->value->right=ptemp->left;
}else if(ptemp->value<pStack->top->value->value){
pStack->top->value->left=ptemp->left;
}
free(ptemp);ptemp=NULL;
}else if(ptemp->left&&ptemp->right){
Elementtype temp=maxNode(ptemp->left);
ptemp->value=temp;
ptemp=ptemp->left;
value=temp;
}else{
free(ptemp);
pTr=NULL;
}
}
}
while(!isemptyStack(pStack)){
parent=popStack(pStack);
parent->bf=getBalance(parent);
if(parent->bf==2||parent->bf==-2){
parent=rotation(parent);
}
if(!isemptyStack(pStack)&&parent->value>pStack->top->value->value){
pStack->top->value->right=parent;
}else if(!isemptyStack(pStack)&&parent->value<pStack->top->value->value){
pStack->top->value->left=parent;
}else{
pTr=parent;
}
}
cleanStack(&pStack);
return pTr;
}
void cleanAVL(AVLT **pTr){ //清空树
if(*pTr){
cleanAVL(&(*pTr)->left);
cleanAVL(&(*pTr)->right);
free(*pTr);
*pTr=NULL;
}
}
void Preordertraversal(AVLT *pTr){ //前序递归遍历
if(pTr){
printf("%d ",pTr->value);
Preordertraversal(pTr->left);
Preordertraversal(pTr->right);
}
}
void Inordertraversal(AVLT *pTr){ //中序递归遍历
if(pTr){
Inordertraversal(pTr->left);
printf("%d ",pTr->value);
Inordertraversal(pTr->right);
}
}
void Postordertraversal(AVLT *pTr){ //后续递归遍历
if(pTr){
Postordertraversal(pTr->left);
Postordertraversal(pTr->right);
printf("%d ",pTr->value);
}
}
int getHAVL(AVLT *pTr){ //递归求树高
int h=0;
if(pTr){
int hl,hr;
hl=getHAVL(pTr->left);
hr=getHAVL(pTr->right);
h=max(hl,hr)+1;
}
return h;
}
int getBalance(AVLT *pTr){ //求平衡因子
if(pTr){
return getHAVL(pTr->left)-getHAVL(pTr->right);
}
}
int max(int a,int b){ //取大值
return a>b?a:b;
}
Elementtype maxNode(AVLT *pTr){ //取左子树的最大值
AVLT *ptemp=pTr->left;
while(ptemp->right){
ptemp=ptemp->right;
}
return ptemp->value;
}
Elementtype minNode(AVLT *pTr){ //取右子树的最小值
AVLT *ptemp=pTr->right;
while(ptemp->left){
ptemp=ptemp->left;
}
return ptemp->value;
}
AVLT *rotation(AVLT *pTr){ //旋转封装
pTr->bf=getBalance(pTr);
if(pTr->bf==2){
if(pTr->left->bf==1){
pTr=ll(pTr);
}else{
pTr=lr(pTr);
}
}
if(pTr->bf==-2){
if(pTr->right->bf==-1){
pTr=rr(pTr);
}else{
pTr=rl(pTr);
}
}
return pTr;
}
AVLT *ll(AVLT *pTr){ //左左旋转
AVLT *ptemp=pTr->left;
pTr->left=ptemp->right;
ptemp->right=pTr;
return ptemp;
}
AVLT *rr(AVLT *pTr){ //右右旋转
AVLT *ptemp=pTr->right;
pTr->right=ptemp->left;
ptemp->left=pTr;
return ptemp;
}
AVLT *lr(AVLT *pTr){ //左右旋转
pTr->left=rr(pTr->left);
pTr=ll(pTr);
return pTr;
}
AVLT *rl(AVLT *pTr){ //右左旋转
pTr->right=ll(pTr->right);
pTr=rr(pTr);
return pTr;
}
/*栈函数*/
Stack *creatStack(){ //创建栈
Stack *pStack=(Stack*)malloc(sizeof(Stack));
pStack->bottom=pStack->top=NULL;
return pStack;
}
int isemptyStack(Stack *pStack){ //判栈空
return pStack->top==NULL;
}
void pushStack(Stack *pStack,Element value){//压栈
STNode *pNode=(STNode*)malloc(sizeof(STNode));
pNode->value=value;
pNode->next=NULL;
if(isemptyStack(pStack)){
pStack->bottom=pStack->top=pNode;
}else{
pNode->next=pStack->top;
pStack->top=pNode;
}
}
Element popStack(Stack *pStack){ //出栈
Element temp=NULL;
if(!isemptyStack(pStack)){
temp=pStack->top->value;
STNode *ptemp=pStack->top;
pStack->top=pStack->top->next;
if(pStack->top==NULL) pStack->bottom=NULL;
free(ptemp);
}else{
printf("空栈!\n");
}
return temp;
}
void cleanStack(Stack **pStack){ //清空栈
if(!isemptyStack(*pStack)){
while((*pStack)->top){
STNode *ptemp=(*pStack)->top;
(*pStack)->top=(*pStack)->top->next;
free(ptemp);
}
}else{
free(*pStack);
*pStack=NULL;
}
}
main函数:
#include <stdio.h>
#include <stdlib.h>
#include "avltree.h"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char *argv[]) {
Elementtype value;
scanf("%d",&value);
AVLT *pTr=NULL;
while(value!=-1){
pTr=insertAVL2(pTr,value);
scanf("%d",&value);
}
Preordertraversal(pTr);printf("\n");
Inordertraversal(pTr);printf("\n");
Postordertraversal(pTr);printf("\n");
pTr=delAVL2(pTr,3);
pTr=delAVL2(pTr,4);
pTr=delAVL2(pTr,5);
Preordertraversal(pTr);printf("\n");
Inordertraversal(pTr);printf("\n");
Postordertraversal(pTr);printf("\n");
return 0;
}