一、介绍
二叉搜索树(Binary Search Tree),或者是一棵空树,或者是具有下列性质的二叉树:
1,若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;2,若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
3,它的左、右子树也分别为二叉搜索树。
二叉搜索树的查找过程和次优二叉树类似,通常采取二叉链表作为二叉搜索序树的存储结构。中序遍历二叉搜索树可得到一个关键字的有序序列,
一个无序序列可以通过构造一棵二叉搜索树变成一个有序序列,构造树的过程即为对无序序列进行排序的过程。每次插入的新的结点都是二叉搜索
树上新的叶子结点,在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可。搜索,插入,删除的复杂度等于树高,
O(log(n)) .
基本结构为:
- typedef int type;
- typedef struct node
- {
- type value;
- struct node *left;
- struct node *right;
- }Search_tree;
二、基本操作
创建和删除二叉搜素树:
- Search_tree *search_tree_create(type value)//创建
- {
- Search_tree *p = (Search_tree*)malloc(sizeof(Search_tree));
- if(NULL == p)
- return NULL;
- p->value = value;
- p->left = p->right = NULL;
- return p;
- }
- void search_tree_destroy(Search_tree *t)//删除(释放)
- {
- if(t)
- {
- if(t->left)
- search_tree_destroy(t->left);
- if(t->right)
- search_tree_destroy(t->right);
- free(t);
- t = NULL;
- }
- }
查找
在二叉搜索树t中查找value的过程为:
1,若t是空树,则搜索失败,否则:
2,若value等于t的根结点的数据域之值,则查找成功;否则:
3,若value小于t的根结点的数据域之值,则搜索左子树;否则:
4,查找右子树。
- Search_tree * search_tree_by_value(Search_tree *t, type value)
- {
- if(t == NULL)
- return NULL;
- if(t->value == value)
- return t;
- else if(t->value > value)
- return search_tree_by_value(t->left, value);
- else
- return search_tree_by_value(t->right, value);
- }
插入
向一个二叉搜索树t中插入一个结点s的算法,过程为:
1,若t是空树,则将创建结点作为根结点插入,否则:
2,若value小于t 的根结点的数据域之值,则把value插入到左子树中,否则:
3,把value插入到右子树中。否则(包括已存在value值的节点) 返回。
- Search_tree *search_tree_insert(Search_tree *t, type value)
- {
- if(t == NULL)// no root
- t = search_tree_create(value);
- else if(t->value > value)
- t->left = search_tree_insert(t->left, value);
- else if(t->value < value)
- t->right = search_tree_insert(t->right, value);
- return t;
- }
在二叉搜索树删去一个结点,分三种情况讨论:
1,若*p结点为叶子结点,即PL(左子树)和PR(右子树)均为空树。由于删去叶子结点不破坏整棵树的结构,则只需修改其双亲结点的指针为空即可。
2,若*p结点只有左子树PL或右子树PR,此时只要令PL或PR直接成为其双亲结点*f的左子树(或者右子树)即可,作此修改也不破坏二叉搜索树的特性。
3,若*p结点的左子树和右子树均不空。在删去*p之后,为保持其它元素之间的相对位置不变,可按中序遍历保持有序进行调整,我们的做法是搜索节点p右子树上值最小的节点min并用min的值代替p的值,最后利用方法2把节点p的右子树的min节点删除即可(可以画图看下,和实际情况符合)。
在二叉搜索树上删除一个结点的算法如下:
- Search_tree *search_tree_delete(Search_tree *t, type value)
- {
- if(t == NULL)
- return NULL;
- Search_tree *p = search_tree_by_value(t, value);
- if(p == NULL)
- {
- printf("no value %d\n", value);
- return NULL;
- }
- if(p->left && p->right)// left right are all exist
- {
- Search_tree *min = search_tree_min(p->right);
- p->value = min->value;
- p->right = search_tree_delete(p->right, min->value);
- }
- else
- {
- Search_tree *temp = p;
- if(p->left) // 左子树非空
- p = p->left;
- else
- p = p->right;
- free(temp);
- temp = NULL;
- }
- return p;
- }
完整代码如下:
- #include <stdio.h>
- #include <stdlib.h>
- typedef int type;
- typedef struct node
- {
- type value;
- struct node *left;
- struct node *right;
- }Search_tree;
- Search_tree *search_tree_create(type value)
- {
- Search_tree *p = (Search_tree*)malloc(sizeof(Search_tree));
- if(NULL == p)
- return NULL;
- p->value = value;
- p->left = p->right = NULL;
- return p;
- }
- void search_tree_destroy(Search_tree *t)
- {
- if(t)
- {
- if(t->left)
- search_tree_destroy(t->left);
- if(t->right)
- search_tree_destroy(t->right);
- free(t);
- t = NULL;
- }
- }
- Search_tree * search_tree_by_value(Search_tree *t, type value)
- {
- if(t == NULL)
- return NULL;
- if(t->value == value)
- return t;
- else if(t->value > value)
- return search_tree_by_value(t->left, value);
- else
- return search_tree_by_value(t->right, value);
- }
- Search_tree *search_tree_min(Search_tree *t)
- {
- if(NULL == t)
- return NULL;
- Search_tree *p = t;
- while(p->left)
- p = p->left;
- return p;
- }
- Search_tree *search_tree_max(Search_tree *t)
- {
- if(NULL == t)
- return NULL;
- Search_tree *p = t;
- while(p->right)
- p = p->right;
- return p;
- }
- Search_tree *search_tree_insert(Search_tree *t, type value)
- {
- if(t == NULL)// no root
- t = search_tree_create(value);
- else if(t->value > value)
- t->left = search_tree_insert(t->left, value);
- else if(t->value < value)
- t->right = search_tree_insert(t->right, value);
- return t;
- }
- Search_tree *search_tree_delete(Search_tree *t, type value)
- {
- if(t == NULL)
- return NULL;
- Search_tree *p = search_tree_by_value(t, value);
- if(p == NULL)
- {
- printf("no value %d\n", value);
- return NULL;
- }
- if(p->left && p->right)// left right are all exist
- {
- Search_tree *min = search_tree_min(p->right);
- p->value = min->value;
- p->right = search_tree_delete(p->right, min->value);
- }
- else
- {
- Search_tree *temp = p;
- if(p->left) // 左子树非空
- p = p->left;
- else
- p = p->right;
- free(temp);
- temp = NULL;
- }
- return p;
- }
- void search_tree_order(Search_tree *t)//中序输出
- {
- if(t == NULL)
- return ;
- search_tree_order(t->left);
- printf("%d ", t->value);
- search_tree_order(t->right);
- }
- int main()
- {
- Search_tree *root = search_tree_create(11);
- search_tree_insert(root, 8);
- search_tree_insert(root, 15);
- search_tree_insert(root, 4);
- search_tree_insert(root, 9);
- search_tree_insert(root, 15);
- search_tree_insert(root, 18);
- search_tree_order(root);
- search_tree_delete(root, 8);
- printf("\n");
- search_tree_order(root);
- search_tree_destroy(root);
- return 0;
- }