zoukankan      html  css  js  c++  java
  • 查找系列之二叉排序树

                                                                        二叉排序树的创建、查询、插入与删除 

    一、简述二叉排序树的思想

          动态查找表中主要有二叉树结构和树结构两种,而二叉树结构分为二叉排序树和平衡二叉树,树结构分为B-树和B+树等。

           二叉排序树能够是一颗空树二叉排序树的性质:二叉排序树上的节点满足左子树<父节点<右子树

           也就是说二叉排序树必须有顺序,且满足左子树<父节点<右子树

    二、构建二叉排序树

            创建二叉排序树通常我们用链式存储结构的节点作为存储单位:如

         

      typedef struct Node{ 
              TypeData data;
              struct Node *leftChild;
              struct Node *rightChild;
      }

          这里我们先讲创建:先初始化得到根节点再来创建二叉排序树,这里必须先申请空间而且赋值后得到了一个新的节点。这时我们须要做的就是怎样满足条件(左子树<父节点<右子树)的插入。所以必须进行一些简单的推断,这里就不多说了,能够看代码。

          创建代码:

     if(root != NULL){
    	        free(root);	
    	   }
    	   root = (BiTreeNode *)malloc(sizeof(BiTreeNode));//申请空间来创建二叉排序树
    	   if(root != NULL){
    	        cout<<"空间申请成功。"<<endl;
    	   }
    	   cout<<"请输入要创建的数据:"<<endl;
    	   cin >> num;
    	   root->data = num;
    	   root->leftChild = NULL;
    	   root->rightChild = NULL;
    	   while(p1 != NULL){
    		   if(p1->data > num&&p1->leftChild!=NULL){
    			   p1 = p1->leftChild;
    		   }else if(p1->data < num&&p1->rightChild!=NULL){
    			   p1 = p1->rightChild;
    		   }else if(p1->data == num){
    		       cout<<"已存在。"<<endl; 
    			   return;
    		   }
    		   if(p1->leftChild == NULL&&num <p1->data){
    			     p1->leftChild= root;
    				 cout<<"创建成功!"<<endl;
    				 break;
    		   }else if(p1->rightChild == NULL && num > p1->data){
    			     p1->rightChild = root;
    				 cout<<"创建成功!

    "<<endl; break; }else{ cout<<"创建失败!"<<endl; continue; } }

    //这里是完整的初始化到创建的代码:

    /**
    *二叉树的初始化获取根节点
    *@param 无
    *@return BiTreeNode 
    */
    BiTreeNode* BiTreeInitiate(){
    	   BiTreeNode *root = NULL;
    	   char c = 0;
    	   int num = 0;
    	   cout<<"请输入第一个根节点你想输入的数据:";cin >>num;
    	   if(root != NULL){
    	        free(root);	
    	   }
    	   root = (BiTreeNode *)malloc(sizeof(BiTreeNode));//申请空间来创建二叉排序树
    	   if(root != NULL){
    	        cout<<"空间申请成功!"<<endl;
    	   }
    	   root->data = num;
    	   root->leftChild = NULL;
    	   root->rightChild = NULL;
    	   return root;
    }
    /**
    *二叉排序树的创建
    *@param  BiTreeNode *root 表示创建的二叉排序的根节点地址
    *@return 无
    */
    void BiTreeCreate(BiTreeNode *pRoot){
    	   TypeData num =0;//在此针对的是以整型数据为例
    	   BiTreeNode *p1 = pRoot;
    	   BiTreeNode * p = NULL;
    	   BiTreeNode *root = NULL;
    	   char c = 0;
    	   if(root != NULL){
    	        free(root);	
    	   }
    	   root = (BiTreeNode *)malloc(sizeof(BiTreeNode));//申请空间来创建二叉排序树
    	   if(root != NULL){
    	        cout<<"空间申请成功!

    "<<endl; } cout<<"请输入要创建的数据:"<<endl; cin >> num; root->data = num; root->leftChild = NULL; root->rightChild = NULL; while(p1 != NULL){ if(p1->data > num&&p1->leftChild!=NULL){ p1 = p1->leftChild; }else if(p1->data < num&&p1->rightChild!=NULL){ p1 = p1->rightChild; }else if(p1->data == num){ cout<<"已存在!"<<endl; return; } if(p1->leftChild == NULL&&num <p1->data){ p1->leftChild= root; cout<<"创建成功!"<<endl; break; }else if(p1->rightChild == NULL && num > p1->data){ p1->rightChild = root; cout<<"创建成功!"<<endl; break; }else{ cout<<"创建失败!

    "<<endl; continue; } } //推断是否继续输入。利用递归的调用来实现对程序的创建 cout<<"是否继续进行创建:Y/N"<<endl; cin >> c; if(c == 'Y' || c == 'y' ){ BiTreeCreate(pRoot); }else if(c == 'N'|| c == 'n'){ cout<<"二叉排序树创建完成!"<<endl; }else{ cout<<"请又一次输入:"<<endl; cin >> c; } }


    三、插入

            二叉排序树的插入其实与创建类似,仅仅只是创建须要不断的插入而插入一次插入一个元素罢了,插入时我们必须推断其是否已经存在,这是就须要对全部的节点进行一次遍历,这时刻以不用遍历全部的。由于二叉排序树是有序的,所以仅仅须要从最小的遍历到大于它的元素就好了。假设不存在就插入反之则返回插入失败。

    代码:

    /**
    *二叉排序树的插入
    *@param BiTreeNode *B 表示创建好了的二叉树表地址
    *@param TypeData num 表示要插入的整型数据
    *@return 无
    */
    void BiTreeInsert(BiTreeNode *B,TypeData num){
            BiTreeNode *current = NULL,*parent = NULL,*p= NULL ;
    		current = B ;//current 指向二叉排序树的头节点
    		//此时须要知道要插入的数据是否已存在,若存在,那么我们呢就不须要再插入。反之插入
    		while(current != NULL){
    			if(current->data == num ){
    			    cout<<"已存在。不须要再进行插入!"<<endl;
    			    return ;
    			}
    			parent = current;//用来记录要插入的数据应该插入的父节点的位置。即记录自己将要插入的位置
    			if(num < current->data&¤t!= NULL){
    		          current = current->leftChild;  	
    			}else if(num > current->data && current != NULL){
    				  current = current->rightChild;	
    			}
    		}
    		//此时已经知道不存在,那么就要申请空间进行插入操做。但要推断是否内存空间满足
    	    p  = (BiTreeNode *)malloc(sizeof(BiTreeNode));
    		if(p == NULL){
    		     cout<<"内存空间不足。"<<endl;
    			 return;
    		}
    		//生成新的节点
    		p->data = num;
    		//临时将左右节点置为空
    		p->leftChild = NULL;
    		p->rightChild = NULL;
    		//这里进行插入操作对其左右节点赋上新的地址
    		if(parent == NULL ){
    		     B = p;
    			 cout<<"插入成功!

    "<<endl; return ; }else if(num < parent->data){ parent->leftChild = p; cout<<"插入成功!"<<endl; return ; }else if(num > parent->data){ parent->rightChild = p; cout<<"插入成功!"<<endl; return ; } }


    四、查找

           查找是非常easy的,仅仅需採用树的遍历即可了,这里採用中序遍历左->根->右,但有两种方式各自是循环和递归,这里採用的是递归啦。

    代码:

    /**
    *二叉排序树的查找
    *@param BiTreeNode *B表示记录二叉排序树的根节点地址
    *@param TypeData num表示要查询的数
    *@return BiTreeNode*
    */
    BiTreeNode* BiTreeSearch(BiTreeNode *B,TypeData num){
    	    BiTreeNode *p = B;//获取根节点地址
    	    if(p == NULL){
    			cout<<"此二叉树为空!"<<endl;
    		    return p;
    	    }
    		if(p->data == num){
    			 cout<<"进入查找操作---------"<<endl;
    		     cout<<"成功的查找到了!num ="<<num<<endl;
    			 cout<<"查找操作完成---------"<<endl;
    			 return p;
    		}else{
    			 if(p->leftChild == NULL&&p->rightChild==NULL){
    				    cout<<"进入查找操作---------"<<endl;
    		            cout<<"查找失败!

    -----------"<<endl; return p; } } if(p->leftChild != NULL){ BiTreeSearch(p->leftChild,num); } if(p->rightChild != NULL){ BiTreeSearch(p->rightChild,num); } if(p->data > num &&p->rightChild == NULL||p->data < num &&p->leftChild == NULL){ return p; } }

    五、改动

             这是一个麻烦的操作,这里就没怎么做好,仅仅是供完好。

    代码:

    /**
    *二叉排序树的改动
    *@param BiTreeNode *B表示记录根节点地址
    *@param TypeData num表示要改动的数
    *@param TypeData d 表示想要改成的数
    *@return 无
    */
    void BiTreeModefy(BiTreeNode *B,TypeData num,TypeData d){
    	    BiTreeNode *p = NULL;
    	    //先要查找到要改动的元素
    	    p=  BiTreeSearch(B,num);       
    		if(p != NULL){
    		     p->data = d;
    			 cout<<"改动成功!

    "<<endl; }else{ cout<<"改动失败!

    "<<endl; } }

    六、删除

              删除时最难的一部分。这里来讲一下删除:

              要做删除就要考虑到其可能的全部情况

               1)要删除的节点无孩子节点,这是仅仅需直接删除就是了

               2)要删除的节点有左孩子节点,这里仅仅需将左孩子节点的地址给其父节点就是了

               3)要删除的节点有右孩子节点。这里仅仅需将右孩子节点给其父节点。然后之前的左孩子节点必须给新的节点

               4)要删除既有左孩子节点又有右孩子节点,那么我们得考虑得把那个节点 放到要删除的节点的位置。这里我们须要做一个推断,即将右边的最小的节点放到要删除的节点的位置,那么这里的重点就是找到这个节点了。我们能够观察发现最左边的叶子节点就是这个节点,更细节,能够看代码调试:

    代码:

    /**
    *二叉排序树的删除
    *这里要靠考虑几种情况,一、删除无孩子的节点;二、删除仅仅有左孩子的节点;三、删除仅仅有右孩子的节点;四、删除既有左孩子又有右孩子的节点
    *@param BiTreeNode *B表示记录的根节点的地址
    *@param TypeData num 表示的是要删除的数
    *@return 无
    */
    void BiTreeDestroy(BiTreeNode *B,TypeData num){
    	    cout<<"删除操作----"<<endl;
    	    BiTreeNode *p = NULL;
    		BiTreeNode *parent = NULL;
    		BiTreeNode *p1 = B;//获取根节点地址
    		BiTreeNode *pLeft = NULL;
    		if(B == NULL){
    		   cout<<"不存在。无法进行删除!"<<endl;
    		   return ;
    		}
    		if(p1 == NULL){
    		            return ;
    		}
    		//这里要获取其父节点
    		while(p1!= NULL){
    			   if(num  ==p1->data){
    				    cout<<"存在这种元素!data="<<p1->data<<endl;
    		            break;
    	           }
    			   parent = p1;
    	           if(num < p1->data){
    			        p1=p1->leftChild;
    			   } 
    			   if(num > p1->data){
    			         p1 = p1->rightChild;
    			   }
    			   if(p1 == NULL && parent->data != num){
    			          cout<<"不存在这样元素!请又一次进行选择和删除!"<<endl;
    					  return ;
    			   }
    		}
    	    //先要查找到要删除的元素
    	    p=  BiTreeSearch(B,num);//获取到了要删除的数的地址
    		if(p == NULL){
    		   cout<<"不存在!

    无法进行删除。"<<endl; return ; } //这里须要推断其属于那种情况 if(p1->leftChild == NULL&&p1->rightChild == NULL){//此时属于无孩子节点的情况 cout<<"------------------------------------------------------无孩子节点"<<endl; if(parent == NULL&&p1!=NULL){ free(p); cout<<"删除成功!-----"<<endl; cout<<"二叉排序树为空!

    不能再进行操作。是否又一次创建。"<<endl; return ; } if(num < parent->data){ parent->leftChild = NULL; }else if(num > parent->data){ parent->rightChild = NULL; } free(p1); cout<<"删除成功。----"<<endl; return ; } if(p1->leftChild != NULL && p1->rightChild == NULL){//此时属于有左孩子节点的情况 cout<<"--------------------------------------------有左孩子节点"<<endl; if(parent == NULL&&p1 != NULL){ //这里不考虑根节点有左右孩子的情况 free(p); cout<<"删除成功!-----"<<endl; cout<<"二叉排序树为空。不能再进行操作。是否又一次创建!"<<endl; return ; } if(num < parent->data){ parent->leftChild = p1->leftChild; }else if(num > parent->data){ parent->rightChild = p1->leftChild; } free(p1); cout<<"删除成功。"<<endl; return ; } if(p1->leftChild == NULL && p1->rightChild != NULL){//此时属于有右孩子的情况 cout<<"----------------------------------------------------有右孩子节点"<<endl; if(parent == NULL&&p1 != NULL){ free(p1); cout<<"删除成功!-----"<<endl; cout<<"二叉排序树为空!不能再进行操作,是否又一次创建!"<<endl; return ; }else if(num < parent->data){ parent->leftChild = p1->rightChild; }else if(num > parent->data){ parent->rightChild = p1->rightChild; } cout<<"删除成功!"<<endl; return ; } if(p1->leftChild != NULL&& p1->rightChild !=NULL ){//此时属于既有右孩子又有左孩子的情况 cout<<"----------------------------------------------------既有左孩子节点也有右孩子节点"<<endl; if(parent == NULL&&p1 != NULL){ free(p1); cout<<"删除成功!-----"<<endl; cout<<"二叉排序树为空!不能再进行操作,是否又一次创建!"<<endl; return ; } if(num <parent->data){ if(p1->rightChild->leftChild == NULL&& p1->rightChild->rightChild == NULL){//这里推断其右节点无孩子节点的情况 p1->rightChild->leftChild = p1->leftChild; /*if(num < parent->data){ parent->leftChild = p1->rightChild; }else{ parent->rightChild = p1->rightChild; }*/ parent->leftChild = p1->rightChild; cout<<"删除成功!

    "<<endl; return; //cout<<"///////"<<p1->leftChild->data<<" "<<p1->rightChild->leftChild->data<<endl; }else if(p1->rightChild->leftChild != NULL ||p1->rightChild->rightChild != NULL){//这里推断其右节点有左孩子节点或右孩子节点 pLeft = p1->rightChild; //获取到了要插入的节点的地址 while( pLeft!= NULL){ if(pLeft->leftChild== NULL ){ break; }else{ pLeft = pLeft->leftChild; } } //运行删除操作 if(p1->rightChild == pLeft){ pLeft->leftChild = p1->leftChild; }else{ if(pLeft->rightChild != NULL){ p1->rightChild->leftChild = pLeft->rightChild ; }else{ p1->rightChild->leftChild = NULL; } pLeft->rightChild = p1->rightChild; pLeft->leftChild = p1->leftChild; } parent->leftChild = pLeft; } free(p1); cout<<"左边-----删除成功!"<<endl; return ; }else if(num > parent->data){ if(p1->rightChild->leftChild == NULL&& p1->rightChild->rightChild == NULL){//这里推断其右节点无孩子节点的情况 p1->rightChild->leftChild = p1->leftChild; parent->rightChild = p1->rightChild; cout<<"删除成功!"<<endl; return; } else if(p1->rightChild->leftChild != NULL ||p1->rightChild->rightChild != NULL){//这里推断其右节点有左孩子节点或右孩子节点 pLeft = p1->rightChild; //获取到了要插入的节点的地址 while( pLeft!= NULL){ if(pLeft->leftChild== NULL ){ break; }else{ pLeft = pLeft->leftChild; } } //运行删除操作 if(p1->rightChild == pLeft){ pLeft->leftChild = p1->leftChild; }else{ if(pLeft->rightChild != NULL){ p1->rightChild->leftChild = pLeft->rightChild ; }else{ p1->rightChild->leftChild = NULL; } pLeft->rightChild = p1->rightChild; pLeft->leftChild = p1->leftChild; } parent->rightChild = pLeft; } free(p1); cout<<"右边---删除成功。"<<endl; return ; } } }


    //这里贴上所有代码以供调试,这里仅仅是实现了基本功能,而且提供了简单的界面操作便于进行完好!

    /**
    *动态查找表有二叉排序树、平衡二叉树、此为二叉树结构。B-树、B+树、此为树结构
    *二叉排序树在左右子树不为空的情况下。左子树小于根小于右子树即左<根<右即没有反复,若已存在,则不在继续插入
    */
    
    
    /**
    *动态查找表,二叉排序树的插入,查找与删除
    *@author 菜鸟
    *@version 2014.7.8
    */
    #include <iostream>
    #include <malloc.h>
    #include <windows.h>
    typedef int TypeData;
    using namespace std;
    //定义二叉树的节点
    typedef struct node{
          TypeData data;
    	  struct node *leftChild;
    	  struct node *rightChild;
    }BiTreeNode;
    /**
    *二叉树的初始化获取根节点
    *@param 无
    *@return BiTreeNode 
    */
    BiTreeNode* BiTreeInitiate(){
    	   BiTreeNode *root = NULL;
    	   char c = 0;
    	   int num = 0;
    	   cout<<"请输入第一个根节点你想输入的数据:";cin >>num;
    	   if(root != NULL){
    	        free(root);	
    	   }
    	   root = (BiTreeNode *)malloc(sizeof(BiTreeNode));//申请空间来创建二叉排序树
    	   if(root != NULL){
    	        cout<<"空间申请成功!

    "<<endl; } root->data = num; root->leftChild = NULL; root->rightChild = NULL; return root; } /** *二叉排序树的创建 *@param BiTreeNode *root 表示创建的二叉排序的根节点地址 *@return 无 */ void BiTreeCreate(BiTreeNode *pRoot){ TypeData num =0;//在此针对的是以整型数据为例 BiTreeNode *p1 = pRoot; BiTreeNode * p = NULL; BiTreeNode *root = NULL; char c = 0; if(root != NULL){ free(root); } root = (BiTreeNode *)malloc(sizeof(BiTreeNode));//申请空间来创建二叉排序树 if(root != NULL){ cout<<"空间申请成功!

    "<<endl; } cout<<"请输入要创建的数据:"<<endl; cin >> num; root->data = num; root->leftChild = NULL; root->rightChild = NULL; while(p1 != NULL){ if(p1->data > num&&p1->leftChild!=NULL){ p1 = p1->leftChild; }else if(p1->data < num&&p1->rightChild!=NULL){ p1 = p1->rightChild; }else if(p1->data == num){ cout<<"已存在!"<<endl; return; } if(p1->leftChild == NULL&&num <p1->data){ p1->leftChild= root; cout<<"创建成功!"<<endl; break; }else if(p1->rightChild == NULL && num > p1->data){ p1->rightChild = root; cout<<"创建成功!

    "<<endl; break; }else{ cout<<"创建失败!

    "<<endl; continue; } } //推断是否继续输入。利用递归的调用来实现对程序的创建 cout<<"是否继续进行创建:Y/N"<<endl; cin >> c; if(c == 'Y' || c == 'y' ){ BiTreeCreate(pRoot); }else if(c == 'N'|| c == 'n'){ cout<<"二叉排序树创建完成!

    "<<endl; }else{ cout<<"请又一次输入:"<<endl; cin >> c; } } /** *二叉排序树的插入 *@param BiTreeNode *B 表示创建好了的二叉树表地址 *@param TypeData num 表示要插入的整型数据 *@return 无 */ void BiTreeInsert(BiTreeNode *B,TypeData num){ BiTreeNode *current = NULL,*parent = NULL,*p= NULL ; current = B ;//current 指向二叉排序树的头节点 //此时须要知道要插入的数据是否已存在,若存在。那么我们呢就不须要再插入,反之插入 while(current != NULL){ if(current->data == num ){ cout<<"已存在。不须要再进行插入。"<<endl; return ; } parent = current;//用来记录要插入的数据应该插入的父节点的位置,即记录自己将要插入的位置 if(num < current->data&¤t!= NULL){ current = current->leftChild; }else if(num > current->data && current != NULL){ current = current->rightChild; } } //此时已经知道不存在,那么就要申请空间进行插入操做。但要推断是否内存空间满足 p = (BiTreeNode *)malloc(sizeof(BiTreeNode)); if(p == NULL){ cout<<"内存空间不足!"<<endl; return; } //生成新的节点 p->data = num; //临时将左右节点置为空 p->leftChild = NULL; p->rightChild = NULL; //这里进行插入操作对其左右节点赋上新的地址 if(parent == NULL ){ B = p; cout<<"插入成功!"<<endl; return ; }else if(num < parent->data){ parent->leftChild = p; cout<<"插入成功!

    "<<endl; return ; }else if(num > parent->data){ parent->rightChild = p; cout<<"插入成功!"<<endl; return ; } } /** *二叉排序树的查找 *@param BiTreeNode *B表示记录二叉排序树的根节点地址 *@param TypeData num表示要查询的数 *@return BiTreeNode* */ BiTreeNode* BiTreeSearch(BiTreeNode *B,TypeData num){ BiTreeNode *p = B;//获取根节点地址 if(p == NULL){ cout<<"此二叉树为空!"<<endl; return p; } if(p->data == num){ cout<<"进入查找操作---------"<<endl; cout<<"成功的查找到了!num ="<<num<<endl; cout<<"查找操作完成---------"<<endl; return p; }else{ if(p->leftChild == NULL&&p->rightChild==NULL){ cout<<"进入查找操作---------"<<endl; cout<<"查找失败。-----------"<<endl; return p; } } if(p->leftChild != NULL){ BiTreeSearch(p->leftChild,num); } if(p->rightChild != NULL){ BiTreeSearch(p->rightChild,num); } if(p->data > num &&p->rightChild == NULL||p->data < num &&p->leftChild == NULL){ return p; } } /** *二叉排序树的改动 *@param BiTreeNode *B表示记录根节点地址 *@param TypeData num表示要改动的数 *@param TypeData d 表示想要改成的数 *@return 无 */ void BiTreeModefy(BiTreeNode *B,TypeData num,TypeData d){ BiTreeNode *p = NULL; //先要查找到要改动的元素 p= BiTreeSearch(B,num); if(p != NULL){ p->data = d; cout<<"改动成功。"<<endl; }else{ cout<<"改动失败。"<<endl; } } /** *二叉排序树的删除 *这里要靠考虑几种情况,一、删除无孩子的节点。二、删除仅仅有左孩子的节点;三、删除仅仅有右孩子的节点。四、删除既有左孩子又有右孩子的节点 *@param BiTreeNode *B表示记录的根节点的地址 *@param TypeData num 表示的是要删除的数 *@return 无 */ void BiTreeDestroy(BiTreeNode *B,TypeData num){ cout<<"删除操作----"<<endl; BiTreeNode *p = NULL; BiTreeNode *parent = NULL; BiTreeNode *p1 = B;//获取根节点地址 BiTreeNode *pLeft = NULL; if(B == NULL){ cout<<"不存在!无法进行删除!

    "<<endl; return ; } if(p1 == NULL){ return ; } //这里要获取其父节点 while(p1!= NULL){ if(num ==p1->data){ cout<<"存在这种元素!data="<<p1->data<<endl; break; } parent = p1; if(num < p1->data){ p1=p1->leftChild; } if(num > p1->data){ p1 = p1->rightChild; } if(p1 == NULL && parent->data != num){ cout<<"不存在这样元素!请又一次进行选择和删除!"<<endl; return ; } } //先要查找到要删除的元素 p= BiTreeSearch(B,num);//获取到了要删除的数的地址 if(p == NULL){ cout<<"不存在!无法进行删除!

    "<<endl; return ; } //这里须要推断其属于那种情况 if(p1->leftChild == NULL&&p1->rightChild == NULL){//此时属于无孩子节点的情况 cout<<"------------------------------------------------------无孩子节点"<<endl; if(parent == NULL&&p1!=NULL){ free(p); cout<<"删除成功!-----"<<endl; cout<<"二叉排序树为空!

    不能再进行操作,是否又一次创建!"<<endl; return ; } if(num < parent->data){ parent->leftChild = NULL; }else if(num > parent->data){ parent->rightChild = NULL; } free(p1); cout<<"删除成功!

    ----"<<endl; return ; } if(p1->leftChild != NULL && p1->rightChild == NULL){//此时属于有左孩子节点的情况 cout<<"--------------------------------------------有左孩子节点"<<endl; if(parent == NULL&&p1 != NULL){ //这里不考虑根节点有左右孩子的情况 free(p); cout<<"删除成功!-----"<<endl; cout<<"二叉排序树为空!

    不能再进行操作。是否又一次创建。"<<endl; return ; } if(num < parent->data){ parent->leftChild = p1->leftChild; }else if(num > parent->data){ parent->rightChild = p1->leftChild; } free(p1); cout<<"删除成功!

    "<<endl; return ; } if(p1->leftChild == NULL && p1->rightChild != NULL){//此时属于有右孩子的情况 cout<<"----------------------------------------------------有右孩子节点"<<endl; if(parent == NULL&&p1 != NULL){ free(p1); cout<<"删除成功!-----"<<endl; cout<<"二叉排序树为空!

    不能再进行操作,是否又一次创建。"<<endl; return ; }else if(num < parent->data){ parent->leftChild = p1->rightChild; }else if(num > parent->data){ parent->rightChild = p1->rightChild; } cout<<"删除成功!

    "<<endl; return ; } if(p1->leftChild != NULL&& p1->rightChild !=NULL ){//此时属于既有右孩子又有左孩子的情况 cout<<"----------------------------------------------------既有左孩子节点也有右孩子节点"<<endl; if(parent == NULL&&p1 != NULL){ free(p1); cout<<"删除成功!-----"<<endl; cout<<"二叉排序树为空!

    不能再进行操作。是否又一次创建!

    "<<endl; return ; } if(num <parent->data){ if(p1->rightChild->leftChild == NULL&& p1->rightChild->rightChild == NULL){//这里推断其右节点无孩子节点的情况 p1->rightChild->leftChild = p1->leftChild; /*if(num < parent->data){ parent->leftChild = p1->rightChild; }else{ parent->rightChild = p1->rightChild; }*/ parent->leftChild = p1->rightChild; cout<<"删除成功。"<<endl; return; //cout<<"///////"<<p1->leftChild->data<<" "<<p1->rightChild->leftChild->data<<endl; }else if(p1->rightChild->leftChild != NULL ||p1->rightChild->rightChild != NULL){//这里推断其右节点有左孩子节点或右孩子节点 pLeft = p1->rightChild; //获取到了要插入的节点的地址 while( pLeft!= NULL){ if(pLeft->leftChild== NULL ){ break; }else{ pLeft = pLeft->leftChild; } } //运行删除操作 if(p1->rightChild == pLeft){ pLeft->leftChild = p1->leftChild; }else{ if(pLeft->rightChild != NULL){ p1->rightChild->leftChild = pLeft->rightChild ; }else{ p1->rightChild->leftChild = NULL; } pLeft->rightChild = p1->rightChild; pLeft->leftChild = p1->leftChild; } parent->leftChild = pLeft; } free(p1); cout<<"左边-----删除成功!

    "<<endl; return ; }else if(num > parent->data){ if(p1->rightChild->leftChild == NULL&& p1->rightChild->rightChild == NULL){//这里推断其右节点无孩子节点的情况 p1->rightChild->leftChild = p1->leftChild; parent->rightChild = p1->rightChild; cout<<"删除成功!

    "<<endl; return; } else if(p1->rightChild->leftChild != NULL ||p1->rightChild->rightChild != NULL){//这里推断其右节点有左孩子节点或右孩子节点 pLeft = p1->rightChild; //获取到了要插入的节点的地址 while( pLeft!= NULL){ if(pLeft->leftChild== NULL ){ break; }else{ pLeft = pLeft->leftChild; } } //运行删除操作 if(p1->rightChild == pLeft){ pLeft->leftChild = p1->leftChild; }else{ if(pLeft->rightChild != NULL){ p1->rightChild->leftChild = pLeft->rightChild ; }else{ p1->rightChild->leftChild = NULL; } pLeft->rightChild = p1->rightChild; pLeft->leftChild = p1->leftChild; } parent->rightChild = pLeft; } free(p1); cout<<"右边---删除成功!"<<endl; return ; } } } /** *二叉树的数据的输出 *@param BiTreeNode *B *@return 无 */ void BiTreeOutPut(BiTreeNode *B){ /*cout<<"B->data="<<B->data<<endl; cout<<"B->rightChild->data="<<B->rightChild->data<<endl; cout<<"B->rightChild->leftChild->data="<<B->rightChild->leftChild->data<<endl; cout<<"B->rightChild->rightChild->data="<<B->rightChild->rightChild->data<<endl; cout<<"B->rightChild->rightChild->leftChild->data="<<B->rightChild->rightChild->leftChild->data<<endl;*/ //输出各个节点的信息,採取中序遍历的方法即左->根->右 if(B == NULL){ return ; } if(B->leftChild != NULL){ BiTreeOutPut(B->leftChild); } cout<<"数据元素:"<<B->data<<endl; if(B->rightChild != NULL){ BiTreeOutPut(B->rightChild); } if(B == NULL){ cout<<"输出完成!

    "<<endl; return ; } } /** *菜单 */ void menu(){ 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<<" |-----------------------------------------------|"<<endl; } int count = 0; void Operation(BiTreeNode *root){ menu(); int input = 0; int num = 0; int d = 0;//要改动的目标元素 cout<<"请选择须要的服务:0-6"<<endl; cin >> input; if(input > 6||input <0){ cout<<"请又一次选择:"<<endl; menu(); Operation(root); } switch(input){ case 0:root = BiTreeInitiate();Operation(root);break; case 1:BiTreeCreate(root);Operation(root);break; case 2:cout<<"请输入要插入的元素:";cin >> num;BiTreeInsert(root,num);Operation(root);break; case 3:cout<<"请输入要查找的元素:";cin >> num;BiTreeSearch(root,num);Operation(root);break; case 4:cout<<"请输入要改动的元素和目标元素:";cin >> num>>d;BiTreeModefy(root,num,d);Operation(root);break; case 5:cout<<"请输入要删除的元素:";cin >> num;BiTreeDestroy(root,num);Operation(root);break; case 6:if(root == NULL){cout<<"已被删除!

    "<<endl;root = BiTreeInitiate();return ;}BiTreeOutPut(root);Operation(root);break; } } int main(){ BiTreeNode *p = NULL; p = BiTreeInitiate();//获取根节点地址 Operation(p); system("PAUSE"); return 0; }

    代码经验证过!





  • 相关阅读:
    HDU 2116 Has the sum exceeded
    HDU 1233 还是畅通工程
    HDU 1234 开门人和关门人
    HDU 1283 最简单的计算机
    HDU 2552 三足鼎立
    HDU 1202 The calculation of GPA
    HDU 1248 寒冰王座
    HDU 1863 畅通工程
    HDU 1879 继续畅通工程
    颜色对话框CColorDialog,字体对话框CFontDialog使用实例
  • 原文地址:https://www.cnblogs.com/wzzkaifa/p/6934084.html
Copyright © 2011-2022 走看看