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

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

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

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

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

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

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

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

生成:

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

posted on 2020-05-27 17:37  夜_归_人  阅读(609)  评论(0编辑  收藏  举报