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


#include <iostream>
#include <stack>
#include <time.h>
using namespace std;

#define max(a,b) ((a)>(b)?(a):(b))
//class AVL tree
class CAvlTree{
private:
	struct node{
		node *left,*right,*parent;
		char value;
		int height;
		node():left(NULL),right(NULL),parent(NULL),value(0),height(1){};
	};
	node *root;
	inline int getheight(node *r){
		if(r==NULL) return 0;
		return r->height;
	}
	inline int getbl(node *r){
		if(r==NULL) return 0;
		return getheight(r->left)-getheight(r->right);
	}
	node* Retate_L(node *r)  
    {  
        node *r1;  
        r1=r->left;  
		r1->parent=r->parent;
        r->left=r1->right;
		if(r1->right!=NULL) r1->right->parent=r;
		r->parent=r1;
        r1->right=r; 
		r->height=max(getheight(r->left),getheight(r->right))+1;
		r1->height=max(getheight(r1->left),getheight(r1->right))+1;
        return r1;  
    }  
    node* Retate_R(node *r)  
    {  
        node *r1;  
        r1=r->right;  
		r1->parent=r->parent;
        r->right=r1->left;
		if(r1->left!=NULL) r1->left->parent=r;
		r->parent=r1;
		r1->left=r;
        r->height=max(getheight(r->left),getheight(r->right))+1;
		r1->height=max(getheight(r1->left),getheight(r1->right))+1;
        return r1;  
    }  
    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* Adjust(node *r,node *q){
		bool bb=false;
		node *fq;
		while(q!=NULL){
			if(q==r) bb=true;
			fq=q->parent;
			q->height=max(getheight(q->left),getheight(q->right))+1;
			if(getbl(q)==2){
				if(getbl(q->left)>=0){ //L
					if(q==r) r=Retate_L(q);
					else if(q==fq->left) fq->left=Retate_L(q);
					else fq->right=Retate_L(q);
				}
				else if(getbl(q->left)==-1){ //RL
					if(q==r) r=Retate_RL(q);
					else if(q==fq->left) fq->left=Retate_RL(q);
					else fq->right=Retate_RL(q);	
				}
			}
			else if(getbl(q)==-2){
				if(getbl(q->right)<=0){ //R
					if(q==r) r=Retate_R(q);
					else if(q==fq->left) fq->left=Retate_R(q);
					else fq->right=Retate_R(q);
				}
				else if(getbl(q->right)==1){ //LR
					if(q==r) r=Retate_LR(q);
					else if(q==fq->left) fq->left=Retate_LR(q);
					else fq->right=Retate_LR(q);	
				}
			}
			if(bb) break;
			q=fq;
		}
		return r;
	}
	node* Delete(node *r,char ch){
		if(r==NULL) return NULL;
		node *p=r;
		//search ch
		while(p!=NULL&&ch!=p->value){
			if(ch<p->value) p=p->left;
			else if(ch>p->value) p=p->right;
		}
		//not searched
		if(p==NULL) return r;
		//replace the node and find the last need delete node p
		while(p->left!=NULL){
			node *q=p->left;
			while(q->right!=NULL) q=q->right;
			p->value=q->value;
			p=q;
		}
		//delete p
		node *fp;
		if(p==r){
			fp=NULL;
			r=p->right;
			if(p->right!=NULL) p->right->parent=p->parent;
			delete p;
		}
		else{
			fp=p->parent;
			if(p->parent->left==p) p->parent->left=p->right;
			else p->parent->right=p->right;
			if(p->right!=NULL) p->right->parent=p->parent;
			delete p;
		}
		//adjust height and retate from q to r;
		r=Adjust(r,fp);
		return r;
	}
	node* Insert(node *r,char ch){
		//new node s
		node *s=new node;
		s->value=ch;
		//insert node 
		if(r==NULL) return s;
		node *p=r,*fp;
		while(p!=NULL){
			fp=p;
			if(ch<p->value) p=p->left;
			else p=p->right;
		}
		if(ch<fp->value) fp->left=s;
		else fp->right=s;
		s->parent=fp;
		//adjust height and retate from q to r;
		r=Adjust(r,fp);
		return r;
	}
public:
	CAvlTree(){
		root=NULL;
	}
	~CAvlTree(){
		Clear();
	}
	void Insert(char ch){
		root=Insert(root,ch);
	}
	void Delete(char ch){
		root=Delete(root,ch);
	}
	void Clear(){
		while(root!=NULL){
			root=Delete(root,root->value);
		}
	}
	friend class CAvlTree_Test;
};

//class test AVL tree
class CAvlTree_Test{
private:
	CAvlTree *t;
	typedef CAvlTree::node node;
	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;
	}
	void PrintSortedTree(){
		stack<node*> st;
		node *p=t->root;
		char lastch=0;
		while(p!=NULL||!st.empty()){
			if(p!=NULL){
				st.push(p);
				p=p->left;
			}
			else{
				p=st.top();st.pop();
				cout<<p->value<<"("<<depth(p->left)<<","<<depth(p->right)<<") ";
				p=p->right;
			}
		}
	}
	bool CheckAvl(){
		stack<node*> st;
		node *p=t->root;
		char lastch=0;
		while(p!=NULL||!st.empty()){
			if(p!=NULL){
				st.push(p);
				p=p->left;
			}
			else{
				p=st.top();st.pop();
				if(depth(p)!=p->height) {
					cout<<"("<<p->value<<")"<<depth(p)<<"!="<<p->height<<endl;
					return false;
				}
				if(abs(t->getheight(p->left)-t->getheight(p->right))>=2){
					cout<<"("<<p->value<<")"<<t->getheight(p->left)<<"-"<<t->getheight(p->right)<<">=2"<<endl;
					return false;
				}
				if(p->left!=NULL&&p->left->parent!=p){
					cout<<"("<<p->value<<")"<<p->left->parent<<"!="<<p<<endl;
					return false;
				}
				if(p->right!=NULL&&p->right->parent!=p){
					cout<<"("<<p->value<<")"<<p->right->parent<<"!="<<p<<endl;
					return false;
				}
				if(lastch>p->value){
					cout<<"("<<p->value<<")lastch="<<lastch<<endl;
					return false;
				}
				p=p->right;
			}
		}
		return true;
	}
	void BeginTest(){
		freopen("test.in","r",stdin);
		freopen("test.out","w",stdout);
		int i,j,n,m;
		cin>>n;
		for(i=0;i<n;i++){
			t=new CAvlTree;
			cout<<"insert["<<i<<"]:"<<endl;
			cin>>m;
			for(j=0;j<m;j++){
				cout<<j<<"->";
				char ch;
				cin>>ch;
				t->Insert(ch);
				cout<<"insert("<<ch<<")->";
				if(CheckAvl()) cout<<"ok"<<endl;
				else cout<<"no"<<endl;
				PrintSortedTree();cout<<endl;
			}
			cout<<"delete["<<i<<":"<<endl;
			for(j=0;j<m;j++){
				cout<<j<<"->";
				char ch;
				cin>>ch;
				t->Delete(ch);
				cout<<"Delete("<<ch<<")->";
				if(CheckAvl()) cout<<"ok"<<endl;
				else cout<<"no"<<endl;
				PrintSortedTree();cout<<endl;
			}
			delete t;
		}
	}
	void RandInitData(){
		freopen("test.in","w",stdout);
		srand(time(NULL)); 
		const int max_test=5;
		const int max_num=200;
		const char max_chr='z';
		const char min_chr='0';
		char chr[max_num];
		int n=max_test,m;
		int i=0,j=0;
		cout<<n*3<<endl;
		for(i=0;i<n;i++){
			m=rand()%max_num+1;
			for(j=0;j<m;j++) chr[j]=rand()%(max_chr-min_chr+1)+min_chr;
			//insert data
			cout<<m<<" ";
			for(j=0;j<m;j++) cout<<chr[j];
			cout<<endl;
			//delete data
			cout<<m<<" ";
			for(j=0;j<m;j++) cout<<chr[j];
			cout<<endl;
			//insert data
			cout<<m<<" ";
			for(j=0;j<m;j++) cout<<chr[j];
			cout<<endl;
			//delete data
			cout<<m<<" ";
			for(j=m-1;j>=0;j--) cout<<chr[j];
			cout<<endl;
			//insert data
			cout<<m<<" ";
			for(j=0;j<m;j++) cout<<chr[j];
			cout<<endl;
			//delete data
			cout<<m<<" ";
			for(j=0;j<m;j++) cout<<chr[rand()%m];
			cout<<endl;
		}
		fclose(stdout);
		freopen("CON","w",stdout);
	}
public:
	void run(){
		RandInitData();
		BeginTest();
	}
};
int main(){	
	CAvlTree_Test * tt= new CAvlTree_Test;
	tt->run();
	delete tt;
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值