【校招VIP】数据结构与算法---二叉排序树

01月09日 收藏 0 评论 0 java开发

【校招VIP】数据结构与算法---二叉排序树

转载声明:文章来源https://blog.csdn.net/mcb199175mcb/article/details/11621339

1.二叉排序树的定义
  二叉排序树(Binary Sort Tree)又称二叉查找(搜索)树(Binary Search Tree)。其定义为:二叉排序树或者是空树,或者是满足如下性质的二叉树:
①若它的左子树非空,则左子树上所有结点的值均小于根结点的值;
②若它的右子树非空,则右子树上所有结点的值均大于根结点的值;
③左、右子树本身又各是一棵二叉排序树。
  上述性质简称二叉排序树性质(BST性质),故二叉排序树实际上是满足BST性质的二叉树。

2.二叉排序树的性质

按中序遍历二叉排序树,所得到的中序遍历序列是一个递增有序序列。

3.二叉排序树的插入
在二叉排序树中插入新结点,要保证插入后的二叉树仍符合二叉排序树的定义。   
插入过程:
若二叉排序树为空,则待插入结点*S作为根结点插入到空树中;   
当非空时,将待插结点关键字S->key和树根关键字t->key进行比较,若s->key = t->key,则无须插入,若s->key< t->key,则插入到根的左子树中,若s->key> t->key,则插入到根的右子树中。而子树中的插入过程和在树中的插入过程相同,如此进行下去,直到把结点*s作为一个新的树叶插入到二叉排序树中,或者直到发现树已有相同关键字的结点为止。

4.二叉排序树的查找
假定二叉排序树的根结点指针为 root ,给定的关键字值为 K ,则查找算法可描述为:
  ① 置初值: q = root ;
  ② 如果 K = q ->data,则查找成功,算法结束;
  ③ 否则,如果 K < q ->data,而且 q 的左子树非空,则将 q 的左子树根送 q ,转步骤②;否则,查找失败,结束算法;
  ④ 否则,如果 K > q ->data ,而且 q 的右子树非空,则将 q 的右子树根送 q ,转步骤②;否则,查找失败,算法结束。

5.二叉排序树的删除
假设被删结点是*p,其双亲是*f,不失一般性,设*p是*f的左孩子,下面分三种情况讨论:   
⑴ 若结点*p是叶子结点,则只需修改其双亲结点*f的指针即可。   
⑵ 若结点*p只有左子树PL或者只有右子树PR,则只要使PL或PR 成为其双亲结点的左子树即可。   
⑶ 若结点*p的左、右子树均非空,先找到*p的中序前趋(或后继)结点*s(注意*s是*p的左子树中的最右下的结点,它的右链域为空),然后有两种做法:① 令*p的左子树直接链到*p的双亲结点*f的左链上,而*p的右子树链到*p的中序前趋结点*s的右链上。② 以*p的中序前趋结点*s代替*p(即把*s的数据复制到*p中),将*s的左子树链到*s的双亲结点*q的左(或右)链上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include<iostream>
using namespace std;
  
struct bitree
{
    int data;
    struct bitree * lchild,*rchild;
};
  
typedef struct bitree bst_tree;
bst_tree *bst_insert(bst_tree *root, int value);
  
/*查找,找到返回1,否则,返回0*/
 int bst_search(bst_tree *root, int value);
  
/*删除节点值为value的节点,成功返回1,否则,返回0*/
 int bst_delete(bst_tree *root, int value);
  
/*中序输出bst树*/
 void bst_print(bst_tree *root);
  
 int main()
{
    int a[12] = {5,4,2,8,7,1,9,3,6,10,11,12};
     int i=0;
     bst_tree *root=NULL;
     for(i=0; i<12; i++)
         root = bst_insert(root, a[i]);
     //bst_delete(root, 5);
     bst_print(root);
     printf("\n%d %d\n", root->data, bst_search(root,13));
     system("pause");
     return 0;
  
}
  
bst_tree *bst_insert(bst_tree *root, int value)
 {
     bst_tree *parent, *node, *child;
     /*树为空,创建根节点*/
     if(root == NULL)
     {
         root = (bst_tree *)malloc(sizeof(bst_tree));
         root->data = value;
         root->lchild = NULL;
         root->rchild = NULL;
         return root;
     }
      
     parent=root;
     node=root;
      while(node != NULL)
     {
         /*待插入数据已经存在,则返回*/
         if(node->data == value)
             return root;
         else
         {
             parent = node;
             /*若小于节点的值,则查看节点的左孩子,否则,查看右孩子*/
             if(node->data < value)
                 node = node->rchild;
             else
                 node = node->lchild;
         }
     }
      
      child = (bst_tree *)malloc(sizeof(bst_tree));
     child->data = value;
     child->lchild = NULL;
     child->rchild = NULL;
  
     if(value > parent->data)
         parent->rchild = child;
    else
         parent->lchild = child;
     return root;
  
  
}
  
int bst_search(bst_tree *root, int value)
{
    bst_tree *p;
     p = root;
    if(p==NULL) return 0;
    if(p->data==value) return 1;
     
    if(p->data>value)
    bst_search(p->lchild,value);
    else
    bst_search(p->rchild,value);
};
  
void bst_print(bst_tree  *root)
{
    if(root==NULL) return;
    bst_print(root->lchild);
    printf("%d  ",root->data);
    bst_print(root->rchild);
}
</iostream>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*删除节点值为value的节点*/
 int bst_delete(bst_tree *root, datatype value)
 {
     bst_tree *p, *pre=NULL, *mid;
      
     p = root;
     if(root == NULL)
         return 0;
          
     /*找到该节点*/
     while((p != NULL) && (p->key != value))
     {
         pre = p;
         if(p->key < value)
         {
             p = p->right;
         }
         else
             p = p->left;
     }
     if(p == NULL)
         return 0;
     /*至少有一个子节点为空*/
     if( (p->left == NULL) || (p->right == NULL) )
     {
         if( pre->left == p )
         {
             pre->left = ( (p->left == NULL) ? p->right : p->left );
         }
         else
             pre->right = ( (p->left == NULL) ? p->right : p->left );
          
         free(p);    /*释放节点*/
     }
     else
     {
         /*删除的节点有2个子女*/
         mid = p->right;
         pre = p;
         /*寻找中序的第一个节点*/
         while(mid->left != NULL)
         {   
             pre = mid;
             mid = mid->left;
         }
         /*移花接木,直接赋值,避免交换节点*/
         p->key = mid->key;
          
         /*将mid节点的子节点作为pre的子节点,并将mid所指向的节点删除*/
         if(pre->right == mid)
             pre->right = mid->right;
         else
             pre->left = mid->right;
         free(mid);
     }
     return 1;
 }
C 0条回复 评论

帖子还没人回复快来抢沙发