zoukankan      html  css  js  c++  java
  • 二叉树操作

    二叉树操作:
    实现以二叉链表为存储结构的二叉树的创建、遍历、查找、插入和删除操作。
    说明:
    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;
    }
    
    
    
    
    


     

  • 相关阅读:
    #Leetcode# 541. Reverse String II
    PAT 甲级 1030 Travel Plan
    PAT 甲级 1029 Median
    bzoj 2002 [Hnoi2010]Bounce 弹飞绵羊
    jzoj 4243. 【五校联考6day1】c
    2019.02.23【NOIP提高组】模拟 A 组 总结
    【GDOI2013模拟1】病毒传播
    【GDOI2013模拟1】最短路
    【GDOI2013模拟1】删数字
    数列分块入门 6 总结
  • 原文地址:https://www.cnblogs.com/lixingle/p/3313006.html
Copyright © 2011-2022 走看看