BST:每个值比左子树的所有值都大,比右子树所有值都小
根节点:没有双亲节点 叶子节点:没有孩子节点
BST插入节点的递归算法:递归在尾部出现,(尾部递归),可以使用迭代更加有效的实现这个算法
BST删除节点:
- 删除没有孩子的节点:直接删除
- 删除有一个孩子的节点:将孩子连接到这个节点的父亲节点
- 删除有两个孩子的节点:(一种方法)删除左子树中值最大的节点(回到1),然后用这个值来替代原来要删除的那个值
BST查找
树的遍历:深度利用递归,分先中后,层次利用队列进行迭代
BST的接口 BST.h
#define TREE_TYPE int
void insert(TREE_TYPE value);
TREE_TYPE *find(TREE_TYPE value);
//一个回调函数,参数是一个函数指针,value将传给这个函数指针指向的函数
void pre_order_tranverse(void (*callback)(TREE_TYPE value));
实现BST同样可以有三种存储的方法
使用静态数组实现
- 节点N的双亲N/2(取整)
- 节点N的左孩子是节点2N
- 节点N的右孩子是节点2N+1
#define "BST.h"
#define <assert.h>
#define <stdio.h>
#define TREE_SIZE 100
#define ARRAY_SIZE
static TREE_TYPE tree[ARRAY_SIZE];
static int left_child(int current)
{
return current*2;
}
static int right_child(int current)
{
return current*2+1;
}
void insert(TREE_TYPE value)
{
int current;
assert(value!=0);//在这颗树里,0是被用来标记未使用的节点
current=1;
while(tree[current]!=0){
if(value < tree[current]){
current = left_child(current);
}
else{
assert(value!=tree[current]);
current = right_child(current);
}
assert(current<ARRAY_SIZE);
}
tree[current]=value;
}
TREE_TYPE * find( TREE_TYPE value )
{
int current;
current = 1;
while(current < ARRAY_SIZE &&tree[current]!=value){
if(value<tree[current])
current = left_child[current];
else
current = right_child[current];
}
if( current < ARRAYSIZE)
return tree+current;
else
return 0;
}
static void do_pre_order_traverse( int current, void(*callback)(TREE_TYPE value))
{
if(current < ARRAY_SIZE && tree[current]!=0){
callback(tree[current]);
do_pre_order_traverse( left_child(current), callback);
do_pre_order_traverse( right_child(current),callback);
}
}
static void pre_order_traverse(void(*callback)(TYPE_TYPE value))
{
do_pre_order_traverse(1,callback);
}
链式的BST实现
#include "BST.h"
#include <assert.h>
#include <stdio.h>
#include <mallco.h>
typedef struct TREE_NODE{
TREE_TYPE value;
struct TREE_NODE* left_child;
struct TREE_NODE* right_child;
}TreeNode;
static TreeNode *tree;
void insert(TREE_TYPE value){
TreeNode* current;
TreeNode** link;
link = &tree;
while((current = *link)!=NULL)
{
if(value < current->value){
link=¤t->left;
}else{
assert(value!=current->value);
link=¤t->right;
}
}
current = (TreeNode*)malloc(sizeof(TreeNode));
assert(current != NULL);
current->value = value;
current->left_child = NULL;
current->right_child = NULL;
*link=current;
}
TREE_TYPE * find(TREE_TYPE value)
{
TreeNode *current;
current=tree;
while(current != NULL && current->value!=value)
{
if(value < current->value)
current = current->leftchild;
else{
assert(value!=current->value);
current = current->rightchild;
}
}
if(current!=NULL)
return ¤t->value;
else
return NULL;
}
static void do_pre_order_traverse( TreeNode* current, void(*callback)(TREE_TYPE value))
{
if(current !=NULL){
callback(current->value);
do_pre_order_traverse( current->left_child, callback);
do_pre_order_traverse( current->right_child,callback);
}
}
static void pre_order_traverse(void(*callback)(TYPE_TYPE value))
{
do_pre_order_traverse(tree,callback);
}