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


發佈了21 篇原創文章 · 獲贊 4 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章