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; }

    代码经验证过!





  • 相关阅读:
    使用Junit等工具进行单元测试
    软件工程学习、问题
    贪吃蛇
    使用Junit工具进行单元测试
    两人组
    软件工程的理解
    使用工具进行单元测试
    对软件工程的理解
    单元测试
    我对软件工程的理解
  • 原文地址:https://www.cnblogs.com/wzzkaifa/p/6934084.html
Copyright © 2011-2022 走看看