⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 8_4.cpp

📁 根据数据文件内的数据对二叉树进行操作。分别完成:二叉树节点数据的插入、删除、查找和打印输出等功能。
💻 CPP
字号:
/*第4题	二叉树操作*/

#include<iostream.h>	
#include<fstream.h>	


#include<iostream.h>
#include<stdlib.h>
template<class T>
class RBtree
{
public:
	enum Color{Red,Black};                    //判断二叉树节点整理情况,red没整理black整理
	
private:
	class RBnode
	{
		T value;
        int i;
		Color color;
		RBnode *p;                               //指父树
		RBnode *left;                            //指左子树
		RBnode *right;                           //指右子树
			RBnode():value(0),color(Red),p(NULL),left(NULL),right(NULL){};
		RBnode(const T &val):value(val),color(Red),p(NULL),left(NULL),right(NULL){};
		friend class RBtree<T>;
	public:
		void Print(int level)
		{
			for(int i=0;i<level;++i)			// 打空格
				cout<<"         ";
			cout<<"|"<<value;					// 打印value(color)
			if (color==Black)
				cout<<"(B)";
			else	
				cout<<"(R)";
			return;
		}
	};
    int i;
    T s;
	double a;
	RBnode *ROOT;            //头节点
	RBnode *NIL;             //末节点
	int alive;				// 计算数据数量
public:
	RBtree():ROOT(new RBnode()),NIL(ROOT),alive(0){NIL->left=NIL->right=NIL->p=NIL;NIL->color=Black;}
	RBtree(const T &val):ROOT(new RBnode(val)),NIL(new RBnode()),alive(1)
	{
		NIL->color=Black;
		NIL->left=NIL->right=NIL->p=NIL;
		ROOT->left=ROOT->right=ROOT->p=NIL;
	}
	~RBtree(){if(ROOT!=NIL)	DeleteAll(ROOT);delete NIL;}
	void Insert(const T&);						//插入数据到二叉数
	void Delete(const T&);	                    // 删除数据
	
	void DP()                                  //由大到小排列
	{
		int i=0;
		dp(ROOT);
	}
     void XP()                                 //由小到大排列
	 {
		int i=0;
		xp(ROOT);
	}
	void dp(RBnode *x)                         //由大到小排列
	{
		
		if(x==NIL) return;
		dp(x->right);
		cout<<x->value<<" ";
	    i++;
		if(!(i%10)) cout<<endl;
		dp(x->left);
	}
	void xp(RBnode *x)                        //由大到小排列 
	{
		
		if(x==NIL) return;
		dp(x->left);
		cout<<x->value<<" ";
		
		if(!(i%10)) cout<<endl;
		dp(x->right);
	}	
	void sum(RBnode *x)                    //求和
	{
		
		if(x==NIL) return;
		sum(x->left);
		s=s+x->value;
		sum(x->right);
	}
	void average()                       //求平均数
	{
		s=0;
		sum(ROOT);
		a=(double)s/alive;
		cout<<a<<endl;
	}


	RBnode *RBFind(const T &val)             // 查找数据
                                            // 找到返回节点否则返回NIL
	{					
		RBnode *tmp=ROOT;
		while((tmp!=NIL)&&(tmp->value!=val))
			tmp=val<tmp->value ? tmp->left : tmp->right;
		return tmp;
	}
	bool Find(const T &val)		// 和上面一样,但找到返回1;没有返回0
	{					
		RBnode *tmp=RBFind(val);
		return (tmp!=NIL);
	}
	RBnode* RBMax(RBnode* start){RBnode *tmp=start;while(tmp->right!=NIL)tmp=tmp->right;return tmp;}
//找最大数
	RBnode* RBMin(RBnode* start){RBnode *tmp=start;while(tmp->left!=NIL)tmp=tmp->left;return tmp;}	
// 找最小数
	RBnode* RBPred(RBnode* start)//找前续
	{
		RBnode *tmp=start;
		if (tmp->left!=NIL)
			tmp=RBMax(tmp->left);
		else
		{
			RBnode *ptmp=tmp;
			tmp=tmp->p;
			while((tmp!=NIL)&&(ptmp!=tmp->right))
			{
				ptmp=tmp;
				tmp=tmp->p;
			}
		}
		return tmp;
	}
	RBnode* RBSucc(RBnode* start)//找后继
	{
		RBnode *tmp=start;
		if (tmp->right!=NIL)
			tmp=RBMin(tmp->right);
		else
		{
			RBnode *ptmp=tmp;
			tmp=tmp->p;
			while((tmp!=NIL)&&(ptmp!=tmp->left))
			{
				ptmp=tmp;
				tmp=tmp->p;
			}
		}
		return tmp;
	}
	void Print();						// prints a RBtree
	void RotateLeft(RBnode*);			// used in inset & delete functions
	void RotateRight(RBnode*);
	int NodeInsert(RBnode*);			// puts a node in the tree
	void FixDel(RBnode*);				// fixing the Delete proc
	T Succ(const T &val)				// printing the successor of sertain value
	{				
		RBnode *tmp=RBFind(val);
		if (tmp==NIL)
		{ 
			cout<<"value not found";
			return 0;
		}
		else
			tmp=RBSucc(tmp);
		return tmp->value;
	}

	T Pred(const T &val)				// the same for predecessor
	{		
		RBnode *tmp=RBFind(val);
		if (tmp==NIL)
		{
			cout<<"value not found";
			return 0;
		}
		else
			tmp=RBPred(tmp);
		return tmp->value;
	}
	
	T Max(const T &val){RBnode *tmp=RBMax(ROOT);return tmp->value;}	//prints max
	T Min(const T &val){RBnode *tmp=RBMin(ROOT);return tmp->value;}	//prints min
	void RBPrint(RBnode*,int);					// req func for printing RBtree
	void DeleteAll(RBnode*);					// deletes all of the RBtree (except the NIL);
};
template<class T>
void RBtree<T>::Insert(const T &val){
	RBnode* x=new RBnode(val),*y;
	if(NodeInsert(x)==1)
	{
		cout<<val<<" alread exist in tree"<<endl;
		return;
	}
	while ((x!=ROOT)&&(x->p->color==Red))
	{
		if (x->p==x->p->p->left)		// if x parent is left son
		{	
			y=x->p->p->right;			// checking x uncle	
			if (y->color==Red)			// if red case 1
			{			
				x->p->color=Black;
				y->color=Black;
				x->p->p->color=Red;
				x=x->p->p;
			}
			else
			{
				if (x==x->p->right)		//if x right the case 2
				{	
					x=x->p;
					RotateLeft(x);
				}
				x->p->color=Black;		// case 3
				x->p->p->color=Red;
				RotateRight(x->p->p);
			}
		}
		else
		{
				y=x->p->p->left;		// checking x uncle	
			if (y->color==Red)			// if red case 4
			{		
				x->p->color=Black;
				y->color=Black;
				x->p->p->color=Red;
				x=x->p->p;
			}
			else
			{
				if (x==x->p->left)		//if x right the case 5
				{	
					x=x->p;
					RotateRight(x);
				}
				x->p->color=Black;		// case 6
				x->p->p->color=Red;
				RotateLeft(x->p->p);
			}
		}
	}
	ROOT->color=Black;
	return;
}
template<class T>
void RBtree<T>::Delete(const T &val)
{
	RBnode *z,*y,*x;
	z=RBFind(val);
	if(z==NIL)
	{
		cout<<val<<" not found"<<endl;
		return;
	}
	--alive;
	if ((z->left == NIL)||(z->right==NIL))	// delteing from leaves
		y=z;
	else
		y=RBSucc(z);
	if (y->left!=NIL)
		x=y->left;
	else 
		x=y->right;
		x->p=y->p;
	if (y->p==NIL)
	{
		ROOT=x;
		x->p=NIL;
	}
	else
	{ 
		if (y==y->p->left)
			y->p->left=x;
		else
			y->p->right=x;
	}
	if (y!=z)				// if we changed the successor with z
		z->value=y->value;
	if (y->color==Black)
		FixDel(x);			// if we delted a Black node we have to rearrange the tree
	delete y;
	if (x==NIL)
		x->p=NIL;
	return;
}
template<class T>
void RBtree<T>::RotateLeft(RBnode* x)
{
	RBnode* y=x->right;
	x->right=y->left;
	if (y->left!=NIL)
		y->left->p=x;
	y->p=x->p;
	if (x->p==NIL)
		ROOT=y;
	else if (x==x->p->left)
		x->p->left=y;
	else
		x->p->right=y;
	y->left=x;
	x->p=y;
	return;
}
template<class T>
void RBtree<T>::RotateRight(RBnode* x)
{
	RBnode* y=x->left;
	x->left=y->right;
	if (y->right!=NIL)
		y->right->p=x;
	y->p=x->p;
	if (x->p==NIL)
		ROOT=y;
	else if (x==x->p->right)
		x->p->right=y;
	else
		x->p->left=y;
	y->right=x;
	x->p=y;
	return;
}
template<class T>
int RBtree<T>::NodeInsert(RBnode *x)
{
	RBnode *tmp1=ROOT,*tmp2=tmp1;
	if (ROOT==NIL)
	{				// in case that x is the 1st node
		ROOT=x;
		x->left=x->right=x->p=NIL;
		++alive;
		return 0;
	}		
	while((tmp1!=NIL)&&(tmp1->value!=x->value))
	{
		tmp2=tmp1;
		tmp1=x->value>tmp1->value ? tmp1->right : tmp1->left;
	}
	if (tmp1==NIL){				// if the item not in tree - add
		if (x->value>tmp2->value)
			tmp2->right=x;
		else
			tmp2->left=x;
		x->p=tmp2;
		x->left=x->right=NIL;
		++alive;
		return 0;
	}
	return 1;
}
template<class T>
void RBtree<T>::FixDel(RBnode *x)
{
	RBnode *w;
	while ((x!=ROOT)&&(x->color==Black))
	{
		if (x==x->p->left){						// if x is the right son
			w=x->p->right;
			if (w->color==Red){					// case 1
				w->color=Black;
				x->p->color=Red;
				RotateLeft(x->p);
				w=x->p->right;
			}
			if ((w->left->color==Black)&&(w->right->color==Black))
			{
				w->color=Red;					// case 2
				x=x->p;
			}else{
				if (w->right->color==Black)
				{	
					w->left->color=Black;		// case 3
					w->color=Red;
					RotateRight(w);
					w=x->p->right;
				}
				w->color=x->p->color;			// case 4
				x->p->color=Black;
				w->right->color=Black;
				RotateLeft(x->p);
				x=ROOT;
			}
		}
		else
		{									// if x is the left son
			w=x->p->left;
			if (w->color==Red)				// case 5
			{				
				w->color=Black;
				x->p->color=Red;
				RotateRight(x->p);
				w=x->p->left;
			}
			if ((w->right->color==Black)&&(w->left->color==Black))
			{
				w->color=Red;					// case 6
				x=x->p;
			}
			else
			{
				if (w->left->color==Black)		// case 7
				{	
					w->right->color=Black;		
					w->color=Red;
					RotateLeft(w);
					w=x->p->left;
				}
				w->color=x->p->color;			// case 8
				x->p->color=Black;
				w->left->color=Black;
				RotateRight(x->p);
				x=ROOT;
			}
		}
	}
	x->color=Black;
	return;
}

template<class T>
void RBtree<T>::Print()
{
	int depth=-1;
	RBnode *x=ROOT;
	RBPrint(x,depth);
	return;
}
// the printing will be done so that the root will be on the left
// and the tree will expend to the right
template<class T>
void RBtree<T>::RBPrint(RBnode *x,int level)
{
	if (x==NIL) return;
	++level;
	RBPrint(x->right,level);
	x->Print(level);
	cout<<"---|"<<endl;
	RBPrint(x->left,level);
	return;
}
template<class T>
void RBtree<T>::DeleteAll(RBnode *x)
{
	if(x==NIL) return;
	DeleteAll(x->left);
	DeleteAll(x->right);
	delete x;
};

//Rbtree.h end
void meun()
	{
		cout<<"          菜单"<<endl;
		cout<<"********************************"<<endl;
		cout<<"   0  结束"<<endl;
		cout<<"   1   插入数据"<<endl;
		cout<<"   2   删除数据"<<endl;
		cout<<"   3   查找数据"<<endl;
		cout<<"   4   找后继数据"<<endl;
		cout<<"   5   找前续数据"<<endl;
		cout<<"   6   找最小值"<<endl;
		cout<<"   7   找最大值"<<endl;
		cout<<"   8   输出二叉数"<<endl;
		cout<<"   9   输出平均值"<<endl;
		cout<<"   10  从大到小输出二叉数"<<endl;
        cout<<"   11  从小到大输出二叉数"<<endl;
	}
void hy()
{
    cout<<"欢迎使用二叉数程序"<<endl;
	cout<<"***************************"<<endl;
	cout<<"0  退出"<<endl;
	cout<<"1  重新输入数据"<<endl;
	cout<<"2  使用存档数据"<<endl;
}

void main(void)
{    
	int l;
    int choice,num;
	RBtree<int> tr;
	hy();
	
	cin>>l;
	cout<<endl;
	switch(l)
	{
	   case(0):return;

	   case(1):
		   cout<<"请输入数据,以-1结束"<<endl;
		   cin>>num;
		   while(num!=-1)
		   {
			   tr.Insert(num);
			   cin>>num;
		   }
		   break;



	   case(2):	
		   {
	           ifstream data("data4.txt", ios::in|ios::nocreate);
	           if(data.bad())
			   {
		           cout<<endl<<"file not found"<<endl;
		
			   }
	           data>>choice;
	           while(!data.eof())
			   {
		          data>>num;
	               tr.Insert(num);
			   }
	           data.close();
		       break;
		   }
     default:cout<<endl<<"the choice number is out of range"<<endl;
			return;
		  }
	tr.Print();
	meun();
	cin>>choice;
	cout<<endl;
	while(choice!=0)
	{
	
		switch(choice)
		{
		case(1):
			cout<<"输入要插入的数"<<endl;
			cin>>num;
			cout<<endl;
			cout<<"插入  "<<num<<endl;
			tr.Insert(num);
			tr.Print();
			break;
		case(2):
            cout<<"输入要删除的数"<<endl;
			cin>>num;
			cout<<"删除 - "<<num<<endl;
			tr.Delete(num);
			break;
		case(3):cout<<"输入要查找的数"<<endl;
			cin>>num;

			cout<<"查找 "<<num<<endl;
			if(tr.Find(num))
				cout<<num<<" 存在"<<endl;
			else 
				cout<<num<<" 不存在"<<endl;
			break;
		case(4):
            cout<<"输入要查找后继数的数"<<endl;
			cin>>num;
			cout<<num<<" 的后继数是"<<endl;
			cout<<tr.Succ(num);
			cout<<endl;
			break;
		case(5):
       cout<<"输入要查找前续数据的数"<<endl;
			cin>>num;
			cout<<num<<"的前续数据是"<<endl;
			cout<<tr.Pred(num);
			cout<<endl;
			break;
		case(6):cout<<"最小值是: ";
			cout<<tr.Min(num);
			cout<<endl;
			break;
		case(7):cout<<"最大值是: ";
			cout<<tr.Max(num);
			cout<<endl;
			break;
		case(8):cout<<"打印二叉数"<<endl;
			tr.Print();
            cout<<endl;
			break;
		case(9):cout<<"平均数是"<<endl;
			tr.average();
            cout<<endl;
			break;
		case(10):cout<<"从大到小是"<<endl;
             tr.DP();
			 cout<<endl;
			break;
        case(11):cout<<"从小到大是"<<endl;
             tr.XP();
             cout<<endl; 
			break;
		default:cout<<endl<<"the choice number is out of range"<<endl;
			break;
		}
        meun();
		cin>>choice;	
	}

	cout<<"二叉数是"<<endl;
	tr.Print();
	cout<<"谢谢使用"<<endl;

	

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -