1、二叉排序树的定义  

二叉排序树(Binary Sort Tree)又称二叉查找(搜索)树(Binary Search Tree)。其定义为:二叉排序树或者是空树,

或者是满足例如以下性质的二叉树:

(1)若它的左子树非空。则左子树上全部结点的值均小于根结点的值;

  (2)若它的右子树非空。则右子树上全部结点的值均大于根结点的值;

  (3)左、右子树本身又各是一棵二叉排序树。

上述性质简称二叉排序树性质(BST性质),故二叉排序树实际上是满足BST性质的二叉树。

2.二叉排序树的性质及意义

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

意义:构造一棵二叉排序树的目的。并非为了排序。而是为了提高查找和插入删除keyword的速度。无论怎么说,

在一个有序数据集上 的查找,速度总要快于无序的数据集,二叉树这样的非线性的结构。也有利于插入和删除的实现。

3.二叉排序树的查找

假定二叉排序树的根结点指针为 root 。给定的keyword值为 K 。则查找算法可描写叙述为:

(1)置初值: q = root ;

(2)假设 K = q -> key ,则查找成功。算法结束。
(3)否则。假设 K < q -> key ,并且 q 的左子树非空。则将 q 的左子树根送 q ,转步骤(2);

否则。查找失败,结束算法;
(4)否则,假设 K > q -> key ,并且 q 的右子树非空。则将 q 的右子树根送 q ,转步骤(2);

否则。查找失败,算法结束。

4.二叉排序树的插入

在二叉排序树中插入新结点,要保证插入后的二叉树仍符合二叉排序树的定义。   

插入步骤例如以下:

(1)若二叉排序树为空,则待插入结点*S作为根结点插入到空树中;   

(2)当非空时,将待插结点keywordS->key和树根keywordt->key进行比較,若s->key = t->key,则无须插入。

若s->key< t->key,则插入到根的左子树中,若s->key> t->key,则插入到根的右子树中。而子树中的插入过程

和在树中的插入过程同样。如此进行下去,直到把结点*s作为一个新的树叶插入到二叉排序树中,或者直到发现

树已有同样keyword的结点为止。

5.二叉排序树的删除

如果被删结点是*p,其双亲是*f。不失一般性,设*p是*f的左孩子。以下分三种情况讨论:   

  (1)若结点*p是叶子结点,则仅仅需改动其双亲结点*f的指针就可以。   
  (2)若结点*p仅仅有左子树PL或者仅仅有右子树PR,则仅仅要使PL或PR 成为其双亲结点的左子树就可以。

  
前趋(或后继)结点*s(注意*s是*p的左子树中的最右下的结点,

它的右链域为空),然后有两种做法:
① 令*p的左子树直接链到*p的双亲结点*f的左链上,而*p的右子树链到*p的中序前趋结点*s的右链上。

② 以*p的中序前趋结点*s取代*p(即把*s的数据拷贝到*p中),将*s的左子树链到*s的双亲结点*q的左(或右)链上。 

6.实现代码例如以下:

bi_search_tree.h

#ifndef __BI_SEARCH_TREE_H__
#define __BI_SEARCH_TREE_H__
 
typedef int datatype;
typedef struct bi_search_tree
{
;
struct bi_search_tree *left,*right;
}bst_tree;
/*插入操作,value是待插入的值*/
bst_tree *bst_insert(bst_tree *root, datatype value);
/*查找,找到返回1。否则,返回0*/
int bst_search(bst_tree *root, datatype value);
/*删除节点值为value的节点,成功返回1,否则,返回0*/
int bst_delete(bst_tree *root, datatype value);
/*中序输出bst树*/
void bst_print(bst_tree *root);
#endif


bi_search_tree.cpp

#include <stdio.h>

#include <stdlib.h>
#include "bi_search_tree.h"
/*插入操作,value是待插入的值*/
bst_tree *bst_insert(bst_tree *root, datatype value)
{
*parent, *node, *child;
/*树为空,创建根节点*/
if(root == NULL)
{
= (bst_tree *)malloc(sizeof(bst_tree));
->key = value;
->left = NULL;
->right = NULL;
return root;
}    
= root;    /*记录下根节点的位置*/
= root;
while(node != NULL)
{
/*待插入数据已经存在,则返回*/
if(node->key == value)
return root;
else
{
= node;
/*若小于节点的值,则查看节点的左孩子,否则,查看右孩子*/
if(node->key < value)
= node->right;
else
= node->left;
}
}
= (bst_tree *)malloc(sizeof(bst_tree));
->key = value;
->left = NULL;
->right = NULL;
    
if(value > parent->key)
->right = child; 
else
->left = child;
return root;
}
/*查找。找到返回1,否则。返回0*/
int bst_search(bst_tree *root, datatype value)
{
*p;
= root;
if(p == NULL)
return 0;
if(p->key == value)
return 1;
else if(p->key > value)
return bst_search(p->left, value);
else
return bst_search(p->right, value);
}
/*删除节点值为value的节点*/
int bst_delete(bst_tree *root, datatype value)
{
*p, *pre=NULL, *mid;
    
= root;
if(root == NULL)
return 0;
        
/*找到该节点*/
while((p != NULL) && (p->key != value))
{
= p;
if(p->key < value)
{
= p->right;
}
else
= p->left;
}
if(p == NULL)
return 0;
/*至少有一个子节点为空*/
if( (p->left == NULL) || (p->right == NULL) )
{
if( pre->left == p )
{
->left = ( (p->left == NULL) ? p->right : p->left );
}
else
->right = ( (p->left == NULL) ? p->right : p->left );
        
free(p);    /*释放节点*/
}
else
{
/*删除的节点有2个子女*/
= p->right;
= p;
/*寻找中序的第一个节点*/
while(mid->left != NULL)
{    
= mid;
= mid->left;
}
/*移花接木,直接赋值,避免交换节点*/
->key = mid->key;
        
/*将mid节点的子节点作为pre的子节点,并将mid所指向的节点删除*/
if(pre->right == mid)
->right = mid->right;
else
->left = mid->right;
free(mid);
}
return 1;
}
/*中序输出bst树*/
void bst_print(bst_tree *root)
{
if(root == NULL)
return;
(root->left);
printf(" %d ", root->key);
(root->right);
}

測试代码:main.cpp

#include <stdio.h>

#include "bi_search_tree.h"
int main()
{
int a[10] = {5,4,2,8,7,1,9,3,6,10};
int i=0;
*root=NULL;
for(i=0; i<10; i++)
= bst_insert(root, a[i]);
(root, 5);
(root);
printf("\n%d %s\n", root->key, bst_search(root, 10) ?
"yes":"no");
return 0;
}