二叉查找树,又称二叉排序树;
二叉查找树的定义:
(1)任意某节点x的左子树y和右子树z,满足key[y]<=key[x]<=key[z];
(2)包含关键字域key,指向左子女指针left_child,指向右子女指针right_child,指向双亲指针parent,卫星数据data;
二叉查找树的查找:
(1)从根节点x开始,逐步下降,比较k与key的大小,相同则查找成功直接返回,否则若k<key,则继续查找x的左子树,否则继续查找x的右子树;递归步骤(1);
(2)其实递归的过程就是,一条由树根下降的过程;
(3)最大关键字是沿右子女指针right_child一直到NIL为止所找到的节点;
(4)最小关键字是沿右子女指针left_child一直到NIL为止所找到的节点;
(5)时间复杂度为O(lgn),空间复杂度为O(1);
二叉查找树的插入:
(1)若是一个空树,直接插入,且该节点为根节点;
(2)插入节点为x,在向下寻找插入位置的过程中,使用指针y始终指向所比较的值z的父节点,比较key(x)和key(z)直到z为NIL,根据走向确定x是y的左孩子还是右孩子;
(3)时间复杂度为O(lgn),空间复杂度为O(1);
二叉查找树的删除:
(1)若所删除的节点x,没有左孩子和右孩子,则直接删除x,并更新其父节点的相关指针域,是NIL成为它的子女;
(2)若所删除的节点x,只有一个孩子,则可删除x,并更新其父节点的相关指针域,使x以前的子女成为它的子女;
(3)若所删除的节点x,有两个孩子,则狸猫换太子,删除以x为根的后继(或前驱)y,用y的值替换x;
(4)时间复杂度为O(lgn),空间复杂度为O(1);
二叉查找树的更新:
(1)先删除某节点,然后再插入该节点;
(2)时间复杂度为O(lgn),空间复杂度为O(1);
程序实现:
#include<stdio.h>
#include<stdlib.h>
#define ARRAY_LENGTH (6)
struct btree_node{
struct btree_node *parent;
struct btree_node *left_child;
struct btree_node *right_child;
int key;
};
int * gendrate_seeds()
{
int* seeds = (int *)malloc(ARRAY_LENGTH * sizeof(int));
srand( (unsigned)time( NULL ) );
int i;
for(i = 0; i < ARRAY_LENGTH; i++){
seeds[i] = rand()%100 +1;
}
return seeds;
}
struct btree_node * init_tree_root()
{
struct btree_node *root_p;
root_p = (struct btree_node *)malloc(sizeof(struct btree_node));
root_p->left_child = NULL;
root_p->right_child = NULL;
root_p->parent = NULL;
return root_p;
}
int tree_search_key(struct btree_node *cmp, int key)
{
if(cmp && cmp->key == key){
return 1;
}else if (cmp && cmp->key > key){
return tree_search_key(cmp->left_child, key); //impotant
}else if (cmp && cmp->key < key){
return tree_search_key(cmp->right_child, key);
}
return 0;
}
struct btree_node * tree_search_insert_node(struct btree_node *cmp, int key)
{
if (cmp && cmp->key >= key){
if(!cmp->left_child)
return cmp;
tree_search_insert_node(cmp->left_child, key);
}else if (cmp && cmp->key < key){
if(!cmp->right_child)
return cmp;
tree_search_insert_node(cmp->right_child, key);
}
}
void tree_insert_node(struct btree_node *root_p, struct btree_node *node)
{
printf("success insert %d\n", node->key);
if(!root_p->left_child && !root_p->right_child){
root_p->left_child = node;
root_p->right_child = node;
node->parent = root_p;
return;
}
struct btree_node* temp;
temp = tree_search_insert_node(root_p->left_child, node->key);
if(temp->key < node->key){
temp->right_child = node;
}else{
temp->left_child = node;
}
node->parent = temp;
}
struct btree_node * tree_search_delete_node(struct btree_node *cmp, int key)
{
if (cmp && cmp->key == key){
return cmp;
}else if (cmp && cmp->key < key){
return tree_search_delete_node(cmp->right_child, key);
}else if (cmp && cmp->key > key){
return tree_search_delete_node(cmp->left_child, key);
}
return NULL;
}
struct btree_node * tree_search_prior(struct btree_node *root)
{
while(root->right_child)
root = root->right_child;
return root;
}
void tree_delete_node(struct btree_node *root_p, int key)
{
struct btree_node* temp;
temp = tree_search_delete_node(root_p->left_child, key);
if(temp == NULL){
printf("con not delete because no this data %d\n", key);
return;
}
if(!temp->left_child && !temp->right_child){//left_child and right_child are all NULL
if(temp->parent->left_child == temp){
temp->parent->left_child = NULL;
}else{
temp->parent->right_child = NULL;
}
free(temp);
printf("success delete %d\n", key);
return;
}
if(!temp->left_child && temp->right_child){//left_child is NULL
if(temp->parent->left_child == temp){
temp->parent->left_child = temp->right_child;
}else{
temp->parent->right_child = temp->right_child;
}
temp->right_child->parent = temp->parent;
free(temp);
printf("success delete %d\n", key);
return;
}
if(temp->left_child && !temp->right_child){//right_child is NULL
if(temp->parent->left_child == temp){
temp->parent->left_child = temp->left_child;
}else{
temp->parent->right_child = temp->left_child;
}
temp->left_child->parent = temp->parent;
free(temp);
printf("success delete %d\n", key);
return;
}
//left_child and right_child are all NOT NULL
printf("success delete %d\n", key);
struct btree_node *prior;
prior = tree_search_prior(temp->left_child);
temp->key = prior->key;
if(prior!= temp->left_child){
prior->parent->right_child = prior->left_child;
}else{
temp->left_child = prior->left_child;
}
if(prior->left_child){
prior->left_child->parent = prior->parent;
}
free(prior);
}
void display_btree_shape(struct btree_node* root, int level)
{
if(root){
display_btree_shape(root->right_child,level+1);
printf("\n");
int i;
for(i = 0; i < level -1; i++)
printf(" ");
printf("%d", root->key);
display_btree_shape(root->left_child,level+1);
}
}
void free_btree(struct btree_node *root_p)
{
while(root_p->left_child)
tree_delete_node(root_p, root_p->left_child->key);
free(root_p);
}
int main(void)
{
int *data = gendrate_seeds();
int datas[] = {45,49,33,101,95};
struct btree_node *root_p = init_tree_root();
int i;
struct btree_node *ss;
for(i = 0; i < ARRAY_LENGTH; i++){
ss = (struct btree_node *)malloc(sizeof(struct btree_node));
ss->key= data[i];
ss->left_child = NULL;
ss->right_child = NULL;
ss->parent = NULL;
tree_insert_node(root_p, ss);
}
for(i = 0; i < sizeof(datas) / sizeof(datas[0]); i++){
ss = (struct btree_node *)malloc(sizeof(struct btree_node));
ss->key= datas[i];
ss->left_child = NULL;
ss->right_child = NULL;
ss->parent = NULL;
tree_insert_node(root_p, ss);
}
display_btree_shape(root_p->left_child, 1);
printf("\n");
int datass = 101;
if(tree_search_key(root_p->left_child, datass) == 1){
printf("success query %d\n", datass);
}else{
printf("fail query %d\n", datass);
}
datass = 99;
if(tree_search_key(root_p->left_child, datass) == 1){
printf("success query %d\n", datass);
}else{
printf("fail query %d\n", datass);
}
printf("--------------------------\n");
tree_delete_node(root_p, 45);
tree_delete_node(root_p, 49);
tree_delete_node(root_p, 33);
tree_delete_node(root_p, 101);
tree_delete_node(root_p, 95);
free_btree(root_p);
free(data);
return 0;
}