zoukankan      html  css  js  c++  java
  • 二叉排序树的实现(生成,查找,删除)

    (若有错误,敬请指正,谢谢!)

    二叉排序树是什么?————> 二叉排序树

       一个待排序数组中,第一个数据元素作为根节点,然后处理数组中后序的每一个元素,生成二叉树;对于之后的每一个元素我们都可以用插入的方式进行生成,相当于在一棵只有根节点的树上不断的进行插入操作,直到生成我们所需的二叉排序树;

       那么对于插入算法来说,我们首先需要找到目前数据元素所需插入节点的地方,通过二叉排序树的节点大小关系(右孩子>根节点>左孩子)我们来定位待插入元素的位置。一般来说,查找也是做得这个工作,只不过插入操作在定位的基础上还需要进行数据的写入;

       最后删除操作有点麻烦,因为我们删除节点后,对剩下的二叉排序树,我们需要更新成一个新的二叉排序树。对于删除的节点我们可以分成三个类型,叶子节点(直接删除)、单侧孩子节点(删除后,还需要把其孩子节点接上)、双侧孩子节点(找到顶替删除节点位置的节点,并处理该节点的孩子);

    叶子节点:直接删除,不用考虑后序因素,我们可以直接把前驱节点的左孩子或右孩子置空,删除叶子节点;(至于直接删除叶子节点,不去管前驱节点的左右孩子,没有详细的实验)

    单侧孩子节点:同样是利用前驱节点处理,该节点后面的孩子占据该节点的位置;

    双侧孩子节点:可以有两种替换方式,一种是查询该节点右子树中最小的元素顶替该节点,一种是查询该节点左子树中最大的元素顶替该节点;这两种实质上都是一样的,都需要处理替换节点的孩子,当然显而易见,该替换节点只可能最多一侧有子树,这是一个比较好的消息。我们首先需要找到该替换节点,也需确定其前驱节点,处理时还需要处理替换节点子树的连接;

    生成:

    1 BiTree CreateBiT(int * array0, int n0) {    // 生成
    2     BiTree BT = NULL;
    3     int i = 0;
    4     while (i < n0) {
    5         InsertBiT(BT, array0[i]);
    6         i++;
    7     }
    8     return BT;
    9 }

    插入:

     1 bool InsertBiT(BiTree & root, int k) {        // 插入
     2     if (root == NULL) {            // 假设数据中不存在相同数据
     3         root = (BiTree)malloc(sizeof(BiTNode));
     4         root->key = k;
     5         root->lchild = root->rchild = NULL;
     6         return true;
     7     }
     8     else if (k < root->key)
     9         return InsertBiT(root->lchild, k);
    10     else
    11         return InsertBiT(root->rchild, k);
    12 }

    查找:(查找算法可能存在一点问题)

     1 int  SearchBiT(BiTree root, int data, BiTree &temp) {    // 查找
     2     if (root == NULL || root->key == data) {
     3         temp = root;
     4         return 1;
     5     }        // 存在非任意值都有返回值问题
     6     if (data < root->key)
     7         SearchBiT(root->lchild, data, temp);
     8     else
     9         SearchBiT(root->rchild, data, temp);
    10 }

    删除:

    叶子节点:

    1 if (p->rchild == NULL && p->lchild == NULL) { // 叶子节点
    2         if (temp->lchild == p)
    3             temp->lchild = NULL;
    4         else
    5             temp->rchild = NULL;
    6     }

    单侧子树节点:

     1 if (p->lchild == NULL) {        // *p节点左子树空判断
     2     if (root == p)
     3         root = p->rchild;
     4     else if (temp->lchild == p)
     5         temp->lchild = p->rchild;
     6     else
     7         temp->rchild = p->rchild;
     8 }
     9 else if (p->rchild == NULL) {    // *p节点右子树空判断
    10     if (root == p)
    11         root = p->lchild;
    12     else if (temp->rchild == p)
    13         temp->lchild = p->lchild;
    14     else
    15         temp->rchild = p->lchild;
    16 }

    双侧子树节点:

     1 BiTree s, par;
     2         s = p->rchild;
     3         par = p;
     4         while (s->lchild != NULL) {
     5             par = s;
     6             s = s->lchild;
     7         }
     8         p->key = s->key;
     9         if (p->rchild->lchild == NULL)
    10             p->rchild = s->rchild;
    11         else
    12             par->lchild = s->rchild;
    13         free(s);

    现在又有很多问题需要我们解决了;

    那么假设只有一个元素,我们如何删除?

    对于没有前驱节点的节点我们该怎么删除?

    为什么双侧子树节点在查找替换节点之后,需要判断   p->rchild->lchild == NULL   ?

    不利用前驱节点,直接写  p = p->rchild / lchild  可行吗?

    全部解决之后,想必二叉排序树也就迎刃而解了;

     

     

    附:

      1 #include<iostream>
      2 #include<cstdlib>
      3 
      4 using namespace std;
      5 
      6 typedef struct BiTNode {// 结点结构
      7     int key;            // 关键字
      8     struct BiTNode  *lchild, *rchild;   // 左右孩子指针
      9 } BiTNode, *BiTree;
     10 
     11 bool InsertBiT(BiTree & root, int k) {        // 插入
     12     if (root == NULL) {            // 假设数据中不存在相同数据
     13         root = (BiTree)malloc(sizeof(BiTNode));
     14         root->key = k;
     15         root->lchild = root->rchild = NULL;
     16         return true;
     17     }
     18     else if (k < root->key)
     19         return InsertBiT(root->lchild, k);
     20     else
     21         return InsertBiT(root->rchild, k);
     22 }
     23 
     24 BiTree CreateBiT(int * array0, int n0) {    // 生成
     25     BiTree BT = NULL;
     26     int i = 0;
     27     while (i < n0) {
     28         InsertBiT(BT, array0[i]);
     29         i++;
     30     }
     31     return BT;
     32 }
     33 
     34 int  SearchBiT(BiTree root, int data, BiTree &temp) {    // 查找
     35     if (root == NULL || root->key == data) {
     36         temp = root;
     37         return 1;
     38     }        // 存在非任意值都有返回值问题
     39     if (data < root->key)
     40         SearchBiT(root->lchild, data, temp);
     41     else
     42         SearchBiT(root->rchild, data, temp);
     43 }
     44 
     45 bool DeleteBiT(BiTree & root, int data) {        // 删除
     46     BiTree p, temp = root, *q = new BiTree;
     47     cout << "*****检测删除数据是否存在*****" << endl;
     48     SearchBiT(root, data, p);
     49     if (p == NULL) {
     50         cout << "不存在该数据,error!" << endl;
     51         return false;
     52     }            
     53     else
     54         cout << "查找成功,数据存在" << endl;
     55     while (temp->rchild != p && temp->lchild != p)
     56         if (temp->key < p->key)        // 无赖之下,求出上一个节点
     57             temp = temp->rchild;
     58         else if (temp->key > p->key)
     59             temp = temp->lchild;
     60         else if (root->lchild == NULL && root->rchild == NULL) {
     61             root = NULL;            // 若判断到此处,表明数据只有一个,并且删除这个元素
     62             return true;
     63         }
     64         else
     65             break;
     66     if (p->rchild == NULL && p->lchild == NULL) { // 叶子节点
     67         if (temp->lchild == p)
     68             temp->lchild = NULL;
     69         else
     70             temp->rchild = NULL;
     71     }
     72     else if (p->lchild == NULL) {        // *p节点左子树空判断
     73         if (root == p)
     74             root = p->rchild;
     75         else if (temp->lchild == p)
     76             temp->lchild = p->rchild;
     77         else
     78             temp->rchild = p->rchild;
     79     }
     80     else if (p->rchild == NULL) {    // *p节点右子树空判断
     81         if (root == p)
     82             root = p->lchild;
     83         else if (temp->rchild == p)
     84             temp->lchild = p->lchild;
     85         else
     86             temp->rchild = p->lchild;
     87     }
     88     else {            // 左右子树都存在
     89         BiTree s, par;
     90         s = p->rchild;
     91         par = p;
     92         while (s->lchild != NULL) {
     93             par = s;
     94             s = s->lchild;
     95         }
     96         p->key = s->key;
     97         if (p->rchild->lchild == NULL)
     98             p->rchild = s->rchild;
     99         else
    100             par->lchild = s->rchild;
    101         free(s);
    102     }
    103     return true;
    104 }
    105 
    106 void InOrder(BiTree Bt) {
    107     if (Bt != NULL) {
    108         InOrder(Bt->lchild);
    109         cout << Bt->key << " ";
    110         InOrder(Bt->rchild);
    111     }
    112 }
    113 
    114 int main()
    115 {
    116     int i, n, v, k;
    117     BiTree Bt, bt = NULL;
    118     cout << "请输入待排数组序列个数,以及待排序列:";
    119     cin >> n;
    120     int *array = new int[n];
    121     for (i = 0; i < n; i++)
    122         cin >> array[i];
    123     Bt = CreateBiT(array, n);
    124     cout << "--------------------" << endl << "请输入查找关键字:v = ";
    125     cin >> v;
    126     SearchBiT(Bt, v, bt);
    127     if (bt == NULL)
    128         cout << "不存在该关键字" << endl;
    129     else
    130         cout << "存在该关键字,v = " << bt->key << " 查找成功!" << endl;
    131     cout << "--------------------" << endl << "请输入删除关键字:w = ";
    132     cin >> v;
    133     k = DeleteBiT(Bt, v);
    134     if (k == 1)
    135         cout << "删除成功!" << endl;
    136     else
    137         cout << "删除失败!" << endl;
    138     cout << "--------------------" << endl << "二叉排序树输出:" << endl;
    139     InOrder(Bt);
    140     if (Bt == NULL)
    141         cout << "数据已全部删除" << endl;
    142     return 0;
    143 }
    View Code

    2020-05-27

  • 相关阅读:
    oracle实验13:单行函数-数字函数
    oracle实验12:单行函数-字符函数
    oracle实验41:编写存储过程
    oracle实验40:编写函数
    oracle实验31:使用PL/SQL,书写一个最简单的块
    oracle实验9-11:使用where和order by子句
    oracle实验6-8:关于null值,列的别名,去掉重复行
    oracle实验5:查询当前用户的所有表和视图
    MD5
    时间戳 日期 转换
  • 原文地址:https://www.cnblogs.com/2015-16/p/12974837.html
Copyright © 2011-2022 走看看