平衡二叉树的创建

1、函数void createnode()用于向一个数组容器中输入节点,最大值为maxsize

void createnode(){
			cout<<"可输入最大节点数: "<<maxsize<<endl;
			cout<<"按递增顺序输入节点,输入-1停止"<<endl;
			datatype a;
			int b=0;
			while(cin>>a){
				nodedata[max]=a;
				max++;
				if(a==-1) break;
			}
			root->data=nodedata[0];
		}

2、函数int create(node*curr)用于将数组中的节点添加到平衡树中,每次都向当前节点的右孩子处添加

int create(node*curr){		
			if(time==max-2) return 0;
			node*nxt;
			nxt=new node();
			curr->data=nodedata[time];
			if(root->Rchild==NULL){		
				root->Rchild=curr;
				curr->par=root;
				updatebalance1(curr);
				create(curr);
			}
			else{
				time++;
				nxt->data=nodedata[time];
				curr->Rchild=nxt;
				nxt->par=curr;
				node*what;
				what=updatebalance1(nxt); 
				if(what!=NULL){		//若发现异常 
					if(Lrotation(what)==true){
						updatebalance2(root);
					}
				}
				create(nxt);		//递归 
			}
		}

3、函数node* updatebalance1(node*curr):每添加一个节点就更新该节点到根节点上的所有节点的平衡因子,发现异常就调用左旋函数

node* updatebalance1(node*curr){		//该函数是在添加节点后更新该节点到根节点路径上所有节点的平衡因子 ,该函数非递归 
			node*curr1;
			curr1=curr;
			curr1->balance=0;
			node*pre;
			pre=curr1->par;
			curr1=pre;
			while(1){
				if(curr1!=root){
					curr1->balance++;
					if(abs(curr1->balance)>1){		//发现异常节点 并返回从该异常节点向下三个节点中的第二个节点 
						return curr1->Rchild; 
					}
					pre=curr1->par;
					curr1=pre;
				}
				else{
					root->balance++;
					if(abs(curr1->balance)>1){		//发现异常节点 并返回从该异常节点向下三个节点中的第二个节点 
						return curr1->Rchild; 
					}
					else
						break;
				}
			}
			return NULL;
		}

4、int updatebalance2(node*curr):这是递归函数,在左旋完成后调用该函数重置平衡因子

int updatebalance2(node*curr){		//该函数是在进行左旋操作后得到新的平衡因子,旋转后的树一定是平衡树,该函数是一个递归函数,参数是根节点,该函数在求左子树的最大高度时用了取巧的办法 
			if(curr==NULL) return 0;
		
			int Rdepth=-1;		//右子树的最大深度
			int Ldepth=-1;		//左子树的最大深度
			node* curr1=curr;
			node *curr2=curr;
			while(curr1!=NULL){
				Rdepth++;
				curr1=curr1->Rchild;
			}
			while(curr2!=NULL){
				Ldepth++;  
				curr2=curr2->Lchild;
			}
			 curr->balance=abs(Rdepth-Ldepth);
			 updatebalance2(curr->Rchild);
		}

5、bool Lrotation(node*curr):左旋函数

bool Lrotation(node*curr){
			if(curr==NULL) return false;
			if(curr->par->par==NULL&&curr->Lchild==NULL){
				curr->par->Rchild=NULL;
				curr->Lchild=curr->par;
				curr->par==NULL;
				root=curr;		//重置根节点 
				root->par=NULL;
				return true;
			}
			else if(curr->par->par==NULL&&curr->Lchild!=NULL){
				node*currLchild;
				node*currpar;
				currpar=curr->par;
				currLchild=curr->Lchild;
				curr->Lchild=curr->par;
				currpar->par=curr;
				currpar->Rchild=currLchild;
				curr->par=NULL;
				root=curr;
				return true;
			}
			else if(curr->par->par!=NULL&&curr->Lchild==NULL){
				node *currpar;
				currpar=curr->par->par;
				curr->par->Rchild=NULL;
				curr->Lchild=curr->par;
				curr->par=NULL;
				curr->par=currpar;
				currpar->Rchild=curr;
				return true;
			}
			else if(curr->par->par!=NULL&&curr->Lchild!=NULL){
				node*currparpar;
				currparpar=curr->par->par;
				node*currLchild;
				currLchild=curr->Lchild;
				curr->Lchild=curr->par;
				curr->par->par=curr;
				curr->Lchild->Rchild=currLchild;
				currparpar->Rchild=curr;
				curr->par=currparpar;
				return false;
			}
		}

6、int printBST(node*curr):打印平衡二叉树

int printBST(node*curr){
			if(curr==NULL) return 0;
			if(curr->Lchild!=NULL||curr->Rchild!=NULL)cout<<"根节点"<<curr->data<<endl;
			if(curr->Lchild!=NULL) {
				cout<<"左孩子"<<curr->Lchild->data<<endl;
			}
			if(curr->Rchild!=NULL){
				cout<<"右孩子"<<curr->Rchild->data<<endl<<endl; 
			} 
			printBST(curr->Lchild);
			printBST(curr->Rchild);
		}

以下是全部代码:

头文件:

#include<iostream>
#include<cmath>
#define maxsize 20
typedef int datatype;
using namespace std;

struct node{
  datatype data;
  node*par;
  node*Lchild;
  node*Rchild;
  int balance;
};

class BBT{  //创建平衡二叉树,输入-1停止创建 
	public:
		BBT(){
			root=new node ();
			root->balance=0;
			cout<<"初始化完成"<<endl;
		}
		
		void createnode(){
			cout<<"可输入最大节点数: "<<maxsize<<endl;
			cout<<"按递增顺序输入节点,输入-1停止"<<endl;
			datatype a;
			int b=0;
			while(cin>>a){
				nodedata[max]=a;
				max++;
				if(a==-1) break;
			}
			root->data=nodedata[0];
		}
		
		int create(node*curr){		
			if(time==max-2) return 0;
			node*nxt;
			nxt=new node();
			curr->data=nodedata[time];
			if(root->Rchild==NULL){		
				root->Rchild=curr;
				curr->par=root;
				updatebalance1(curr);
				create(curr);
			}
			else{
				time++;
				nxt->data=nodedata[time];
				curr->Rchild=nxt;
				nxt->par=curr;
				node*what;
				what=updatebalance1(nxt); 
				if(what!=NULL){		//若发现异常 
					if(Lrotation(what)==true){
						updatebalance2(root);
					}
				}
				create(nxt);		//递归 
			}
		}
		
		node* updatebalance1(node*curr){		//该函数是在添加节点后更新该节点到根节点路径上所有节点的平衡因子 ,该函数非递归 
			node*curr1;
			curr1=curr;
			curr1->balance=0;
			node*pre;
			pre=curr1->par;
			curr1=pre;
			while(1){
				if(curr1!=root){
					curr1->balance++;
					if(abs(curr1->balance)>1){		//发现异常节点 并返回从该异常节点向下三个节点中的第二个节点 
						return curr1->Rchild; 
					}
					pre=curr1->par;
					curr1=pre;
				}
				else{
					root->balance++;
					if(abs(curr1->balance)>1){		//发现异常节点 并返回从该异常节点向下三个节点中的第二个节点 
						return curr1->Rchild; 
					}
					else
						break;
				}
			}
			return NULL;
		}
		int updatebalance2(node*curr){		//该函数是在进行左旋操作后得到新的平衡因子,旋转后的树一定是平衡树,该函数是一个递归函数,参数是根节点,该函数在求左子树的最大高度时用了取巧的办法 
			if(curr==NULL) return 0;
		
			int Rdepth=-1;		//右子树的最大深度
			int Ldepth=-1;		//左子树的最大深度
			node* curr1=curr;
			node *curr2=curr;
			while(curr1!=NULL){
				Rdepth++;
				curr1=curr1->Rchild;
			}
			while(curr2!=NULL){
				Ldepth++;  
				curr2=curr2->Lchild;
			}
			 curr->balance=abs(Rdepth-Ldepth);
			 updatebalance2(curr->Rchild);
		}
		
		bool Lrotation(node*curr){
			if(curr==NULL) return false;
			if(curr->par->par==NULL&&curr->Lchild==NULL){
				curr->par->Rchild=NULL;
				curr->Lchild=curr->par;
				curr->par==NULL;
				root=curr;		//重置根节点 
				root->par=NULL;
				return true;
			}
			else if(curr->par->par==NULL&&curr->Lchild!=NULL){
				node*currLchild;
				node*currpar;
				currpar=curr->par;
				currLchild=curr->Lchild;
				curr->Lchild=curr->par;
				currpar->par=curr;
				currpar->Rchild=currLchild;
				curr->par=NULL;
				root=curr;
				return true;
			}
			else if(curr->par->par!=NULL&&curr->Lchild==NULL){
				node *currpar;
				currpar=curr->par->par;
				curr->par->Rchild=NULL;
				curr->Lchild=curr->par;
				curr->par=NULL;
				curr->par=currpar;
				currpar->Rchild=curr;
				return true;
			}
			else if(curr->par->par!=NULL&&curr->Lchild!=NULL){
				node*currparpar;
				currparpar=curr->par->par;
				node*currLchild;
				currLchild=curr->Lchild;
				curr->Lchild=curr->par;
				curr->par->par=curr;
				curr->Lchild->Rchild=currLchild;
				currparpar->Rchild=curr;
				curr->par=currparpar;
				return false;
			}
		}
		
		int printBST(node*curr){
			if(curr==NULL) return 0;
			if(curr->Lchild!=NULL||curr->Rchild!=NULL)cout<<"根节点"<<curr->data<<endl;
			if(curr->Lchild!=NULL) {
				cout<<"左孩子"<<curr->Lchild->data<<endl;
			}
			if(curr->Rchild!=NULL){
				cout<<"右孩子"<<curr->Rchild->data<<endl<<endl; 
			} 
			printBST(curr->Lchild);
			printBST(curr->Rchild);
		}
		
		node* returnroot(){
			return root;
		}								
		
	private:
		node*root;
		datatype nodedata[maxsize];
		int time=1;//记录递归次数
		int max=0;//记录节点容量 
};

cpp文件:

#include<iostream>
#include"BalanceBST.h"
using namespace std;
int main(){
	BBT use;
	node *curr;
	curr=new node();
	use.createnode();
	use.create(curr);
	use.printBST(use.returnroot());
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值