数据结构——平衡二叉树

一、定义:

        平衡二叉树(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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值