二叉树操作

二叉树操作:
实现以二叉链表为存储结构的二叉树的创建、遍历、查找、插入和删除操作。
说明:
1、按先序遍历思想创建二叉树;
2、分别实现中序遍历和层次遍历;
3、给定元素值查找结点指针位置并返回其指针,可利用指针引用data域输出;
4、实现插入左右孩子操作,指定元素值,找到结点后若已存在对应位置的孩子结点则不插入;
5、删除指定元素值的结点,若该结点存在子树则将其子树所有结点全部删除回收;
6、程序提供简单功能菜单

 

 

// TreeTest1.cpp : 定义控制台应用程序的入口点。
//


#include <iostream>
using namespace std;
//定义一个二叉树 数据结构
typedef struct BiTNode{
char date;				//数据成员
struct BiTNode *lchild,*rchild;
} biTNode,* BiTree;

//定义一个队,层次遍历时用
typedef struct Dui{
char chardate;
struct Dui *next;
}* LDui;
//判断队是否为空
bool isEmpaty(LDui D){
	if (D->next==NULL){
		return true;
	}else 
		return false;

}
//入队操作
void PushDui(LDui D,char pchar){
	while (D->next!=NULL){
		D=D->next;
	} 
	
	D->next=new Dui;
	D->next->chardate=pchar;
	D->next->next=NULL;

}
//出队函数,返回值char类型
char PopDui(LDui D){

	char pchar;
	if(D->next!=NULL){	
		pchar=D->next->chardate;//吧头结点后的节点付给pchar
	}else {
		pchar='#';
		return pchar;
	}
	if (D->next->next!=NULL){
		D->next=D->next->next;
	}else {
		D->next=NULL;
	}
	return pchar;

}
//用线序遍历创建二叉树
BiTree CreateBiTree( ){
	//声明一个二叉树指针类型
	BiTree T;	
	char myChar;     //定义一个字符串myChar;
	cout<<"请输入字符"<<endl;
	cin >>myChar;
	if (myChar=='#')   //如果输入‘#’表示是节点
	{T=NULL;
	return T;
	}
	else {	
		T=new BiTNode; 
//Step1.赋值根节点
	
		T->date=myChar;
//Step2.创建左子树
		T->lchild=CreateBiTree( );
//Step3.创建右子树
		T->rchild=CreateBiTree( );
		return T;
	}
	return T;    //返回指向结构体变量的指针
} 
//通过父节点,返回孩子节点······························
bool returnSun(BiTree T,char f,char &sun1,char &sun2){

	
	BiTree top=T;
	if(T==NULL){
	 return false;
	}
	if(T->date!=f){
		if (T->lchild!=NULL)
		returnSun(T->lchild, f,sun1,sun2);
		if (T->rchild!=NULL)
		returnSun(T->rchild, f,sun1,sun2);
	
	}else {
		//cout<<f<<" 字符已找到lelelell!"<<endl;
		if (T->lchild!=NULL) {      //如果左孩子不为空,把其值储存到sun1中
				sun1=T->lchild->date;
		}else {
				sun1='#';
		}
		if (T->rchild!=NULL)  {     //如右孩子不为空,把其值储存到sun2中
				sun2=T->rchild->date;
		}else {
				sun2='#';
		}

	return true;
	}
	
	 return false;	
}


//层次遍历二叉树
void CengCi(BiTree T){

	BiTree Top=T;
	LDui TopDui;
	TopDui=new Dui;
cout<<endl<<"层次遍历二叉树: "<<endl;
	TopDui->next=NULL;
	if (T!=NULL){  //如果头结点不为空,读出头结点。
		cout <<T->date<<endl;
		//如果左孩子不为空,入队
		if (T->lchild!=NULL){
			PushDui(TopDui,T->lchild->date);
		}
		//如果右孩子不为空,入队
	
		if (T->rchild!=NULL){
			PushDui(TopDui,T->rchild->date);
		}
	}
	//while 队不为空,出队 ,读该节点,把孩子入队
	char pchar;
	char sun1,sun2;

	if (!isEmpaty(TopDui)){
		while (!isEmpaty(TopDui)){
			//出队
    		pchar=PopDui(TopDui);
			//找到pchar 读出它````````````````````````````
			cout<<pchar<<endl;
			returnSun(T,pchar,sun1,sun2);//获得出队元素的左右孩子
			if(sun1!='#'){//如果左孩子不为空。则入队			
				PushDui(TopDui,sun1);	
			}
			if(sun2!='#'){//如果右孩子不为空。则入队	
				PushDui(TopDui,sun2);		
			} 		
		}
	}

}

//中序遍历二叉树,参数为指向结构体变量的指针
void MidTree(BiTree Tree){	
	BiTree top=Tree;
	if(top!=NULL){    //如果节点不为空
		
		MidTree(top->lchild); //先序遍历左子树
		cout<<top->date<<endl;//输出节点数
		MidTree(top->rchild);//先序遍历右子树
	}

}

//先序遍历二叉树,参数为指向结构体变量的指针
void PreTree(BiTree Tree){
	
	BiTree top=Tree;
	if(top!=NULL){    //如果节点不为空
		cout<<top->date<<endl;//输出节点数
		PreTree(top->lchild); //先序遍历左子树	
		PreTree(top->rchild);//先序遍历右子树
	}

}
//查找节点元素  如果T中存在字符f则返回true,并打印出一句话”f 字符已找到!“。否则返回false
bool findTree(BiTree T,char f){
	BiTree top=T;
	if(T==NULL){
	 return false;
	}
	if(T->date!=f){
		findTree(T->lchild, f);
		findTree(T->rchild, f);
	
	}else {
		cout<<f<<" 字符已找到!!!!!"<<endl;
	return true;
	}
	
	 return false;	
}
/*

插入节点元素,如果找不到要插入节点的双亲则返回false 找到结点后若已存在对应
位置的孩子结点则不插入返回false ,若找到结点后没有字节点 ,则插入节点元素返回true
*/
bool TreeInsert(BiTree T,char parent,char insert){
	BiTree top=T;
	BiTNode  *node;
	if(T==NULL){
	 return false;
	}
	
	
	if(T->date==parent ) {

		if (T->lchild!=NULL&&T->rchild!=NULL){
		 return false;
		  }
			if (T->lchild==NULL){
				node=new BiTNode;
				node->date=insert;
				node->lchild=NULL;
				node->rchild=NULL;
				T->lchild=node;
			
				cout <<"插入成功"<<endl;
				return true;
			}else if (T->rchild==NULL){
				node=new BiTNode;
				node->date=insert;
				node->lchild=NULL;
				node->rchild=NULL;
				T->rchild=node;
				
				cout <<"插入成功"<<endl;
				return true;
			}
			
	
	   } else if(T->date!=parent){
		TreeInsert(T->lchild,parent,insert);
		TreeInsert(T->rchild,parent,insert);
		
	    }
	
	 return false;	
}
//定义删除节点函数,第一个参数为指向树的指针,第二个参数为要删除的节点字符
bool delNode(BiTree T,char delchar){	
	if (T!=NULL){//如果跟节点不为空
			if (T->date==delchar){//如果根节点为要删除的节点···
				cout<<"已找到节点!!下面执行删除····"<<endl;
				/**/
				delete T->lchild;
				T->lchild=NULL;
				delete T->rchild;
				T->rchild=NULL;
			    delete T;
				T=new BiTNode;
				T->lchild=NULL;
				T->rchild=NULL;			
				return true;

			}else if (T->lchild!=NULL&&T->lchild->date==delchar){//如果左孩子为要删除的节点
				cout <<"删除左孩子:"<<endl;
				delete T->lchild->lchild;
				delete T->lchild->rchild;
				delete T->lchild;
				T->lchild=NULL;
				return true;
			
			}else if (T->rchild!=NULL&&T->rchild->date==delchar){//如果左孩子为要删除的节点
					cout <<"删除右孩子:"<<endl;			

					delete T->rchild->lchild;
					delete T->rchild->rchild;
					delete T->rchild;
					T->rchild=NULL;
					return true;
			}else {
				if(T->lchild!=NULL){   //如果左孩子不为空
					delNode(T->lchild,delchar);
				}
				if(T->rchild!=NULL){	//如果右孩子不为空
					delNode(T->rchild,delchar);
				}
			
			}
	}
	

return false;

}


//定义目录函数
void Report(){
	cout <<endl<<"功能菜单介绍:	"<<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;

}


BiTree BTree;//定义一个全局变量 树

int ReportMethod(){
		char CC;
		Report();//输出目录
		cout <<endl<<"请输入数字:"<<endl;
	  cin >>CC;
	
	  while(CC!=0){
			switch(CC){
			case '0':
					return 0;
			case '1':
				//先序遍历创建树	 
	            BTree=CreateBiTree();	
				break;
			case '2':			
			    cout<<"先序遍历结果:"<<endl;
	            PreTree(BTree);//调用先序遍历 				 
				break;
			case '3':
				//层次遍历
				CengCi(BTree);						
				break;
			case '4':
				 cout<<"中序遍历结果:"<<endl;
				MidTree(BTree);//调用中序遍历
				break;
	    	case '5':
				//插入字符
					char myinsert;
					cout<<"输入你要插入的字符"<<endl;
					cin>>myinsert;
					cout<<"请输入你要插入字符的双亲:"<<endl;
					char charparent;
					cin >>charparent;

					TreeInsert(BTree,charparent,myinsert);
					cout<<"先序遍历结果:"<<endl;
   					PreTree(BTree);
				
			break;		
			case '6':
				//删除节点
				char delchar;
				cout <<"请输入你要删除的节点字符:"<<endl;
				cin >>delchar;
				delNode(BTree,delchar);
				break;

			case '7':
					//调用查找树的节点函数
					cout<<"查找字符串"<<endl;
					char f;
					cout<<"请输入你要查找的字符"<<endl;
					cin>>f;	
					findTree(BTree, f);
					
				break;
			default :    //如果输入错误
			  cout <<"输入错误!!!请重新输入!"<<endl;			 
			  break;	
			}
		     	Report();//输出目录
				cout <<endl<<"请输入数字:"<<endl;
	            cin >>CC;
	  }
return 0;
}

//主函数

int main(){
ReportMethod(); //调用函数
return 0;
}





 

原文地址:https://www.cnblogs.com/lixingle/p/3313006.html