二叉搜索树 c 语言实现

来源:互联网 发布:双11淘宝报名入口 编辑:程序博客网 时间:2024/05/15 21:31

一、介绍

二叉搜索树(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_find(Search_tree *t, type value)//根据指定值查找{if(t == NULL)return NULL;if(t->value == value)return t;else if(t->value > value)return search_tree_find(t->left, value);elsereturn search_tree_find(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 roott = 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节点删除即可(可以画图看下,和实际情况符合)。
在二叉搜索树上删除一个结点的算法如下:

bool search_tree_delete(Search_tree *t, type value)//删除节点{if(t == NULL)return false;Search_tree *p=t,*prev;//while(p && p->value!=value)    {        prev=p;        if(p->value>value)            p=p->left;        else            p=p->right;    }if(p == NULL)return false;if(p->left && p->right)// left right  are all exist{    Search_tree *min=p->right;//右子树最小节点    prev=p;    while(min->left)//找到右子树最小节点        {            prev=min;            min=min->left;        }        p->value=min->value;//把找到的右子树的最值与p进行值交换        /*将min节点的子节点作为prev的子节点,并将min所指向的节点删除*/        if(prev->right==min)            prev->right=min->right;//        else            prev->left=min->right;}else{    if(prev->left==p)//p为左        {            prev->left=p->left ? p->left:p->right;        }        else if(prev->right==p)//p为右        {            prev->right=p->left ? p->left:p->right;        }        free(p);        p=NULL;}return true;}

完整代码如下

#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_find(Search_tree *t, type value)//根据指定值查找{if(t == NULL)return NULL;if(t->value == value)return t;else if(t->value > value)return search_tree_find(t->left, value);elsereturn search_tree_find(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 roott = 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;}bool search_tree_delete(Search_tree *t, type value)//删除节点{if(t == NULL)return false;Search_tree *p=t,*prev;//while(p && p->value!=value)    {        prev=p;        if(p->value>value)            p=p->left;        else            p=p->right;    }if(p == NULL)return false;if(p->left && p->right)// left right  are all exist{    Search_tree *min=p->right;//右子树最小节点    prev=p;    while(min->left)//找到右子树最小节点        {            prev=min;            min=min->left;        }        p->value=min->value;//把找到的右子树的最值与p进行值交换        /*将min节点的子节点作为prev的子节点,并将min所指向的节点删除*/        if(prev->right==min)            prev->right=min->right;//        else            prev->left=min->right;}else{    if(prev->left==p)//p为左        {            prev->left=p->left ? p->left:p->right;        }        else if(prev->right==p)//p为右        {            prev->right=p->left ? p->left:p->right;        }        free(p);        p=NULL;}return true;}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, 6);search_tree_insert(root, 18);search_tree_order(root);search_tree_delete(root, 11);printf("\n");search_tree_order(root);search_tree_delete(root, 4);printf("\n");search_tree_order(root);search_tree_destroy(root);return 0;}


原创粉丝点击