• 二叉搜索树的查找、删除、插入


      1 #include<iostream>
      2 
      3 using namespace std;
      4 
      5 //二叉搜索树
      6 typedef struct BiNode
      7 {
      8     int data;
      9     struct BiNode *lchild; //这里定义的是BiNode的指针类型
     10     struct BiNode *rchild;
     11 
     12 }BiNode ,*BiTree; //这里面的BiTree前面有一个星星,表示这种结构的指针类型
     13 
     14 //sousuo
     15 //这里的*T代表的是二叉排序树,key表示的是要查找的值 ,f是指向*T的双亲,p是指向查找路线上的最后一个节点
     16 int searchnum(BiTree *T,BiTree f, int key ,BiTree *p) //这里的p一定要有指针或者引用,避免值传递
     17 {
     18     if(!(*T))
     19     {
     20         *p = f ;
     21         return 0;
     22     }
     23     else if(key == (*T)->data)
     24     {
     25         *p = *T;
     26         return 1;
     27     }
     28     else if (key > (*T)->data)
     29     {
     30         searchnum(& ((*T)->rchild) ,*T,key,p); //f是父节点,在这里的赋值体现出来
     31 
     32     }
     33     else 
     34     {
     35         searchnum(& ( (*T)->lchild) ,*T,key,p);
     36     }
     37 }
     38 //插入操作
     39 int insertnum(BiTree &T,int key)
     40 {
     41     BiTree *p = (BiTree *)malloc(sizeof(BiNode));
     42 
     43     if(searchnum(&T,NULL,key,p) != 0 )  //已经有该关键字,不需要插入了
     44     {
     45         return 0;
     46     }
     47     else
     48     {
     49         BiTree s = (BiTree )malloc(sizeof(BiNode));
     50         s->data = key;
     51         s->lchild = s->rchild = NULL;
     52             
     53         if (!(*p))//这里忘了一种情况那就是空树的插入操作 
     54         {
     55             T = s;
     56         }
     57         else if(key > (*p)->data)
     58         {
     59             (*p)->rchild = s;
     60         }
     61         else 
     62         {
     63             (*p)->lchild = s; // 这里不存在等于的那种情况,要不然当一个if就已经检测出来了
     64         }
     65     //然后整个做完之后,看起来似乎无懈可击,但是这样子完全不对的,涉及值传递和址传递的过程
     66         //上面的函数接口部分应该写上函数的值或者引用,因为输出的结果要造成T在整个函数运行后,只得到改变
     67         //我这里为了方便,不更改下面的代码 直接加了一个引用
     68     }
     69 }
     70 
     71 
     72 //00删除操作
     73 
     74 void Delete(BiTree *p)
     75 {
     76     
     77     BiTree s;
     78     if((*p)->lchild == NULL)
     79     {
     80         s = (*p);
     81         (*p) = (*p)->rchild;
     82         free(s);
     83     }
     84     else if( (*p)->rchild == NULL)
     85     {
     86         s = (*p);
     87         (*p) = (*p)->lchild;
     88         free(s); 
     89     }
     90     else  //这种情况两个孩子都不能空了
     91     {
     92         BiTree q,s;
     93         q= (*p);
     94         s= (*p)->lchild; // 这里要取第一个做孩子,向右遍历,到左右的孩子来替换删除节点
     95         while(s->rchild)
     96         {
     97             q = s;
     98             s = s->rchild;
     99         }
    100         //这里忘记了替换,找到删除节点的 中序遍历相邻节点 要进行替换的。
    101         (*p)->data = s->data ; //这里容易写成(*p)=s ,为什么不能这么写呢,因为这么写就改变了他的结构了,左右孩子都变了。
    102         //下面就分两种情况了,就是q有没有移动,换言之就是删除节点的左孩纸有没有节点。
    103         //这一步是已经完成了删除,剩下删除的节点左子树的烂摊子要收拾
    104         if(q == (*p))
    105         {
    106             (q)->lchild = s->lchild;
    107         }
    108         else
    109         {
    110             (q)->rchild = s->lchild;
    111         }
    112 
    113         free(s);
    114     
    115 
    116     }
    117 }
    118 
    119  int deletenum(BiTree *T ,int key)
    120  {
    121      if(*T )
    122      {
    123          return 0;
    124      }
    125      else
    126      {
    127         if(key  == (*T)->data)
    128         {
    129             Delete(T);
    130         }
    131         else if(key >(*T)->data )
    132         {
    133             deletenum(&(*T)->rchild ,key);
    134         }
    135         else
    136         {
    137             deletenum(&(*T)->lchild ,key);
    138         }
    139      }
    140  }
    141 
    142 int main()
    143 {
    144     system("pause");
    145 }

    注意事项:

    • 注意值传递和址传递的情况,希望传入的值有所改变,并且在调用函数外部依旧用到这个值,就用址传递,其他时候都可以了
    • 在删除的时候,要释放空间
    • 删除操作的时候,删除节点要赋值,注意有种情况是直接赋值的,而不是节点相等,赋值后,对之后改变的子树进行操作。
  • 相关阅读:
    STL常见用法
    7-1 求a/b的高精度值 (70分)
    迷宫问题
    ES6新特性之箭头函数语法
    2020软件工程作业05
    2020软件工程作业04
    CTF之SQL注入1
    CTF之Git泄露
    CTF之网站源码
    CTF之HTTP基础认证
  • 原文地址:https://www.cnblogs.com/xiaochige/p/8540671.html
Copyright © 2020-2023  润新知