二叉搜索树

一、介绍

二叉搜索树(Binary Search Tree),或者是一棵空树,或者是具有下列性质的二叉树:

1,若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
2,若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
3,它的左、右子树也分别为二叉搜索树。

二叉搜索树的查找过程和次优二叉树类似,通常采取二叉链表作为二叉搜索序树的存储结构。中序遍历二叉搜索树可得到一个关键字的有序序列,

一个无序序列可以通过构造一棵二叉搜索树变成一个有序序列,构造树的过程即为对无序序列进行排序的过程。每次插入的新的结点都是二叉搜索

树上新的叶子结点,在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可。搜索,插入,删除的复杂度等于树高,

O(log(n)) .

基本结构为:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. typedef int type;  
  2. typedef struct node  
  3. {  
  4.     type value;  
  5.     struct node *left;  
  6.     struct node *right;  
  7. }Search_tree;  

二、基本操作

创建和删除二叉搜素树:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Search_tree *search_tree_create(type value)//创建  
  2. {  
  3.     Search_tree *p = (Search_tree*)malloc(sizeof(Search_tree));  
  4.     if(NULL == p)  
  5.         return NULL;  
  6.     p->value = value;  
  7.     p->left = p->right = NULL;   
  8.     return p;  
  9. }  
  10.   
  11. void search_tree_destroy(Search_tree *t)//删除(释放)  
  12. {  
  13.     if(t)  
  14.     {  
  15.         if(t->left)  
  16.             search_tree_destroy(t->left);  
  17.         if(t->right)  
  18.             search_tree_destroy(t->right);  
  19.         free(t);  
  20.         t = NULL;  
  21.     }  
  22. }  

查找
在二叉搜索树t中查找value的过程为:
1,若t是空树,则搜索失败,否则:
2,若value等于t的根结点的数据域之值,则查找成功;否则:
3,若value小于t的根结点的数据域之值,则搜索左子树;否则:
4,查找右子树。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Search_tree * search_tree_by_value(Search_tree *t, type value)  
  2. {  
  3.     if(t == NULL)  
  4.         return NULL;  
  5.     if(t->value == value)  
  6.         return t;  
  7.     else if(t->value > value)   
  8.         return search_tree_by_value(t->left, value);  
  9.     else  
  10.         return search_tree_by_value(t->right, value);  
  11. }  

插入
向一个二叉搜索树t中插入一个结点s的算法,过程为:
1,若t是空树,则将创建结点作为根结点插入,否则:
2,若value小于t 的根结点的数据域之值,则把value插入到左子树中,否则:
3,把value插入到右子树中。否则(包括已存在value值的节点) 返回。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Search_tree *search_tree_insert(Search_tree *t, type value)  
  2. {  
  3.     if(t == NULL)// no root  
  4.         t = search_tree_create(value);  
  5.     else if(t->value > value)  
  6.         t->left = search_tree_insert(t->left, value);  
  7.     else if(t->value < value)  
  8.         t->right = search_tree_insert(t->right, value);  
  9.     return t;  
  10. }  
删除
在二叉搜索树删去一个结点,分三种情况讨论:
1,若*p结点为叶子结点,即PL(左子树)和PR(右子树)均为空树。由于删去叶子结点不破坏整棵树的结构,则只需修改其双亲结点的指针为空即可。
2,若*p结点只有左子树PL或右子树PR,此时只要令PL或PR直接成为其双亲结点*f的左子树(或者右子树)即可,作此修改也不破坏二叉搜索树的特性。
3,若*p结点的左子树和右子树均不空。在删去*p之后,为保持其它元素之间的相对位置不变,可按中序遍历保持有序进行调整,我们的做法是搜索节点p右子树上值最小的节点min并用min的值代替p的值,最后利用方法2把节点p的右子树的min节点删除即可(可以画图看下,和实际情况符合)。
在二叉搜索树上删除一个结点的算法如下:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Search_tree *search_tree_delete(Search_tree *t, type value)  
  2. {  
  3.     if(t == NULL)  
  4.         return NULL;  
  5.     Search_tree *p = search_tree_by_value(t, value);  
  6.     if(p == NULL)  
  7.     {  
  8.         printf("no value %d\n", value);  
  9.         return NULL;  
  10.     }  
  11.     if(p->left && p->right)// left right  are all exist  
  12.     {  
  13.         Search_tree *min = search_tree_min(p->right);  
  14.         p->value = min->value;  
  15.         p->right = search_tree_delete(p->right, min->value);  
  16.     }  
  17.     else  
  18.     {  
  19.         Search_tree *temp = p;  
  20.         if(p->left) // 左子树非空  
  21.             p = p->left;  
  22.         else   
  23.             p = p->right;  
  24.         free(temp);  
  25.         temp = NULL;  
  26.     }  
  27.     return p;  
  28. }  

完整代码如下:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. typedef int type;  
  5. typedef struct node  
  6. {  
  7.     type value;  
  8.     struct node *left;  
  9.     struct node *right;  
  10. }Search_tree;  
  11.   
  12. Search_tree *search_tree_create(type value)  
  13. {  
  14.     Search_tree *p = (Search_tree*)malloc(sizeof(Search_tree));  
  15.     if(NULL == p)  
  16.         return NULL;  
  17.     p->value = value;  
  18.     p->left = p->right = NULL;   
  19.     return p;  
  20. }  
  21.   
  22. void search_tree_destroy(Search_tree *t)  
  23. {  
  24.     if(t)  
  25.     {  
  26.         if(t->left)  
  27.             search_tree_destroy(t->left);  
  28.         if(t->right)  
  29.             search_tree_destroy(t->right);  
  30.         free(t);  
  31.         t = NULL;  
  32.     }  
  33. }  
  34.   
  35. Search_tree * search_tree_by_value(Search_tree *t, type value)  
  36. {  
  37.     if(t == NULL)  
  38.         return NULL;  
  39.     if(t->value == value)  
  40.         return t;  
  41.     else if(t->value > value)   
  42.         return search_tree_by_value(t->left, value);  
  43.     else  
  44.         return search_tree_by_value(t->right, value);  
  45. }  
  46.   
  47. Search_tree *search_tree_min(Search_tree *t)  
  48. {  
  49.     if(NULL == t)  
  50.         return NULL;  
  51.     Search_tree *p = t;  
  52.     while(p->left)  
  53.         p = p->left;  
  54.     return p;  
  55. }  
  56.   
  57. Search_tree *search_tree_max(Search_tree *t)  
  58. {  
  59.     if(NULL == t)  
  60.         return NULL;  
  61.     Search_tree *p = t;  
  62.     while(p->right)  
  63.         p = p->right;  
  64.     return p;  
  65. }  
  66.   
  67. Search_tree *search_tree_insert(Search_tree *t, type value)  
  68. {  
  69.     if(t == NULL)// no root  
  70.         t = search_tree_create(value);  
  71.     else if(t->value > value)  
  72.         t->left = search_tree_insert(t->left, value);  
  73.     else if(t->value < value)  
  74.         t->right = search_tree_insert(t->right, value);  
  75.     return t;  
  76. }  
  77.   
  78. Search_tree *search_tree_delete(Search_tree *t, type value)  
  79. {  
  80.     if(t == NULL)  
  81.         return NULL;  
  82.     Search_tree *p = search_tree_by_value(t, value);  
  83.     if(p == NULL)  
  84.     {  
  85.         printf("no value %d\n", value);  
  86.         return NULL;  
  87.     }  
  88.     if(p->left && p->right)// left right  are all exist  
  89.     {  
  90.         Search_tree *min = search_tree_min(p->right);  
  91.         p->value = min->value;  
  92.         p->right = search_tree_delete(p->right, min->value);  
  93.     }  
  94.     else  
  95.     {  
  96.         Search_tree *temp = p;  
  97.         if(p->left) // 左子树非空  
  98.             p = p->left;  
  99.         else   
  100.             p = p->right;  
  101.         free(temp);  
  102.         temp = NULL;  
  103.     }  
  104.     return p;  
  105. }  
  106.   
  107. void search_tree_order(Search_tree *t)//中序输出  
  108. {  
  109.     if(t == NULL)  
  110.         return ;  
  111.     search_tree_order(t->left);  
  112.     printf("%d ", t->value);  
  113.     search_tree_order(t->right);  
  114. }  
  115.   
  116. int main()  
  117. {  
  118.     Search_tree *root = search_tree_create(11);  
  119.     search_tree_insert(root, 8);  
  120.     search_tree_insert(root, 15);  
  121.     search_tree_insert(root, 4);  
  122.     search_tree_insert(root, 9);  
  123.     search_tree_insert(root, 15);  
  124.     search_tree_insert(root, 18);  
  125.     search_tree_order(root);  
  126.     search_tree_delete(root, 8);  
  127.     printf("\n");  
  128.     search_tree_order(root);  
  129.     search_tree_destroy(root);  
  130.     return 0;  
  131. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值