平衡二叉树C++模板

输出是中序遍历,相当于排序二叉树,看树形修改printf位置即可

有错误请指出,网上很多平衡树的代码其实是错的...

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
using namespace std;

typedef struct Node {
	int data;
	int BF;
	struct Node *lc,*rc;
} Node,*Tree;

void LR(Tree *p) { //左旋
	Tree R;
	R=(*p)->rc;
	(*p)->rc=R->lc;
	R->lc=(*p);
	*p=R;
}

void RR(Tree *p) { //右旋
	Tree L;
	L=(*p)->lc;
	(*p)->lc=L->rc;
	L->rc=(*p);
	*p=L;
}

void LB(Tree *T) {
	Tree L,Lr;
	L=(*T)->lc;
	switch(L->BF) {
		case 1://新节点插入在T的左孩子的左子树上,做单右旋处理
			(*T)->BF=L->BF=0;
			RR(T);
			break;
		case -1://新插入节点在T的左孩子的右子树上,做双旋处理
			Lr=L->rc;
			switch(Lr->BF) {
				case 1:
					(*T)->BF=-1;
					L->BF=0;
					break;
				case 0:
					(*T)->BF=L->BF=0;
					break;
				case -1:
					(*T)->BF=0;
					L->BF=1;
					break;
			}
			Lr->BF=0;
			LR(&(*T)->lc);
			RR(T);
	}
}

void RB(Tree *T) {
	Tree R,Rl;
	R=(*T)->rc;
	switch(R->BF) {
		case -1://新节点插在T的右孩子的右子树上,要做单左旋处理
			(*T)->BF=R->BF=0;
			LR(T);
			break;
		case 1://新节点插在T的右孩子的左子树上,要做双旋处理
			Rl=R->lc;
			switch(Rl->BF) {
				case 1:
					(*T)->BF=0;
					R->BF=-1;
					break;
				case 0:
					(*T)->BF=R->BF=0;
					break;
				case -1:
					(*T)->BF=1;
					R->BF=0;
					break;
			}
			Rl->BF=0;
			RR(&(*T)->rc);
			LR(T);
	}
}

bool insert(Tree *T,int x,bool *taller) { //变量taller反应T长高与否
	if(!*T) {
		*T=(Tree)malloc(sizeof(Node));
		(*T)->data=x;
		(*T)->lc=(*T)->rc=NULL;
		(*T)->BF=0;
		*taller=true;
	} else {
		if(x==(*T)->data) { //不插入
			*taller=false;
			return false;
		}
		if(x<(*T)->data) {
			//以下为左子树插入
			if(!insert(&(*T)->lc,x,taller))//未插入
				return false;
			if(*taller) {  //插入左子树,左子树深度增加
				switch((*T)->BF) {
					case 1://深度若为1,则开始调整
						LB(T);
						*taller=false;
						break;
					case 0://左右子树等深,左子树变深
						(*T)->BF=1;
						*taller=true;
						break;
					case -1://右子树比左子树深,左右子树等深
						(*T)->BF=0;
						*taller=false;
						break;
				}
			}
		} else {
			//以下为右子树插入
			if(!insert(&(*T)->rc,x,taller))
				return false;
			if(*taller) { //插入右子树,右子树深度增加
				switch((*T)->BF) {
					case 1://左子树比右子树深,左右子树等深
						(*T)->BF=0;
						*taller=false;
						break;
					case 0://左右子树等深,右子树变深
						(*T)->BF=-1;
						*taller=true;
						break;
					case -1://深度若为-1,则开始调整 
						RB(T);
						*taller=false;
						break;
				}
			}
		}
	}
	return true;
}

void ZX(Node *T) {
	if(T!=NULL) {
		ZX(T->lc);
		printf("%d ",T->data);
		ZX(T->rc);
	}

}
int main() {
	int n,A[1005];
	scanf("%d",&n);
	for(int i=0; i<n; i++) {
		scanf("%d",&A[i]);
	}
	Tree T=NULL;
	bool taller;
	for(int i=0; i<n; i++)
		insert(&T,A[i],&taller);
	ZX(T);
	printf("\n");
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值