平衡二叉树插入、删除(递归算法)

本文介绍了一种自平衡二叉搜索树——AVL树的C++实现方法,并提供了插入、删除、查找等核心操作的具体实现细节。同时,通过一个完整的示例程序展示了如何使用AVL树来维持数据的有序性和平衡性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


#include <iostream>
#include <stack>
using namespace std;

#define max(a,b) ((a)>(b)?(a):(b))

class CAvlTree{
private:
	struct node{
		node *left;
		node *right;
		char value;
		int height;
		node():left(NULL),right(NULL),value(0),height(1){};
	};
	node *root;
	inline int GetHeight(node *r){
		if(r==NULL) return 0;
		else return r->height;
	}
	inline int GetBL(node *r){   //计算平衡因子
		if(r==NULL) return 0;
		else return GetHeight(r->left) - GetHeight(r->right);
	}
	node* Retate_L(node *r){    
		node *p;
		p=r->left;
		r->left=p->right;
		p->right=r;
		r->height=max(GetHeight(r->left),GetHeight(r->right))+1;
		p->height=max(GetHeight(p->left),GetHeight(p->right))+1;
		return p;
	}
	node* Retate_R(node *r){
		node *p;
		p=r->right;
		r->right=p->left;
		p->left=r;
		r->height=max(GetHeight(r->left),GetHeight(r->right))+1;
		p->height=max(GetHeight(p->left),GetHeight(p->right))+1;
		return p;
	}
	node* Retate_LR(node *r){
		r->right=Retate_L(r->right);
		return Retate_R(r);
	}
	node* Retate_RL(node *r){
		r->left=Retate_R(r->left);
		return Retate_L(r);
	}
	node* Insert(node *r,char ch){  //插入字符ch
		if(r==NULL){
			r=new node;
			r->value=ch;
			return r;
		}
		else{
			if(ch<r->value){
				r->left=Insert(r->left,ch);
				r->height=max(GetHeight(r->left),GetHeight(r->right))+1;
				if(GetBL(r)==2){
					if(GetBL(r->left)==1){      //L
						r=Retate_L(r);
					}
					else if(GetBL(r->left)==-1){ //RL
						r=Retate_RL(r);
					}
				}
			}
			else{
				r->right=Insert(r->right,ch);
				r->height=max(GetHeight(r->left),GetHeight(r->right))+1;
				if(GetBL(r)==-2){
					if(GetBL(r->right)==-1){   //R
						r=Retate_R(r);     
					}
					else if(GetBL(r->right)==1){ //LR
						r=Retate_LR(r);   
					}
				}
			}
			return r;
		}
	}
	node *Delete_p(node *r,node *p){  //删除指定节点p
		if(r==p){
			node *q;
			if(p->left==NULL){
				q=p->right;
				delete p;
				return q;
			}
			else if(p->right==NULL){
				q=p->left;
				delete p;
				return q;
			}
			else{
				q=p->left;
				while(q->right!=NULL) q=q->right;
				r->value=q->value;
				r->left=Delete_p(r->left,q);
				r->height=max(GetHeight(r->left),GetHeight(r->right))+1;
				if(GetBL(r)==-2){
					if(GetBL(r->right)<=0){ //R
						r=Retate_R(r);   
					}
					else if(GetBL(r->right)==1){ //LR
						r=Retate_LR(r);  
					}
				}
				return r;
			}
		}
		else if(p->value<r->value){
			r->left=Delete_p(r->left,p);
			r->height=max(GetHeight(r->left),GetHeight(r->right))+1;
			if(GetBL(r)==-2){
				if(GetBL(r->right)<=0){ //R
					r=Retate_R(r);   
				}
				else if(GetBL(r->right)==1){ //LR
					r=Retate_LR(r);  
				}
			}
			return r;
		}
		else{
			r->right=Delete_p(r->right,p);
			r->height=max(GetHeight(r->left),GetHeight(r->right))+1;
			if(GetBL(r)==2){
				if(GetBL(r->left)>=0){      //L
					r=Retate_L(r);
				}
				else if(GetBL(r->left)==-1){ //RL
					r=Retate_RL(r);
				}
			}
			return r;
		} 
	}
	node *Search(node *r,char ch){  //查找字符ch
		if(r==NULL){
			return NULL;
		}
		else{
			if(ch<r->value){
				return Search(r->left,ch);
			}
			else if(ch>r->value){
				return Search(r->right,ch);
			}
			else{
				return r;
			}
		}
	}
	node *Delete(node *r,char ch){  //删除字符ch
		node *p=Search(r,ch);
		if(p==NULL) return NULL;
		return Delete_p(r,p);
	}
	void inorder(){   //二叉树前序遍历,输出有序序列
		stack<node*> st;
		node *p=root;
		while(p!=NULL||!st.empty()){
			if(p!=NULL){
				st.push(p);
				p=p->left;
			}
			else{
				p=st.top();st.pop();
				cout<<p->value<<"("<<p->height<<")"<<" ";
				p=p->right;
			}
		}
	}
	int depth(node *r){
		if(r==NULL) return 0;
		int ld,rd;
		ld=depth(r->left);
		rd=depth(r->right);
		return max(ld,rd)+1;
	}
	bool Check(node *r){      //检查平衡二叉树是否平衡
		if(r==NULL) return true;
		if(r->height!=depth(r)) return false;
		if(abs(depth(r->left)-depth(r->right))>=2) return false;
		if(!Check(r->left)) return false;
		if(!Check(r->right)) return false;
		return true;
	}
public:
	CAvlTree(){
		root=NULL;
	}
	void Insert(char ch){
		root=Insert(root,ch);
	}
	void Delete(char ch){
		root=Delete(root,ch);
	}
	void PrintSort(){
		inorder();
		cout<<endl;
	}
	bool CheckAvl(){
		return Check(root);
	}
};
int main(){
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
	
	int n;
	cin>>n;
	while(n-->0){
		CAvlTree *t=new CAvlTree;
		int k;
		cin>>k;
		cout<<n<<":"<<endl;
		while(k-->0){
			char ch;
			cin>>ch;
			t->Insert(ch);
			cout<<"insert("<<ch<<")->"<<t->CheckAvl()<<":";
			t->PrintSort();
		}
		cin>>k;
		while(k-->0){
			char ch;
			cin>>ch;
			t->Delete(ch);
			cout<<"delete("<<ch<<")->"<<t->CheckAvl()<<":";
			t->PrintSort();
		}
		delete t;
	}
	return 0;
}
输入数据test.in:
2
36 0123456789abcdefghijklmnopqrstuvwxyz
36 zyxwvutsrqponmlkjihgfedcba9876543210
36 13579mlk246wvutsr8onjihg0zyxedcqpfba
36 13jihgf24576xwpocbvut890zysnmlkedrqa
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值