二叉查找树的优缺点
优点
二叉查找树的查找成功的平均时间复杂度为log(n),二叉查找树中序遍历输出有序序列,因此也叫二叉排序树。
缺点
最坏情况下,二叉查找树的查找成功的时间复杂度为O(n)。比如,序列是一个有序序列的情况。二叉查找树对缓存不友好。
代码实现
#include <stdio.h>
#include <stdlib.h>
typedef struct BSTNode{
int data;
struct BSTNode *lchild;
struct BSTNode *rchild;
}BSTNode, *BSTree;
// 搜索结点
BSTree search(BSTree BST, BSTree f, BSTree *p, int data){
if(BST == NULL) { // 如果没找到,记录空结点的前驱结点
*p = f;
return NULL;
}
if(BST->data == data){ // 如果找到,记录该结点
*p = BST;
return BST;
}else if(data < BST->data){
return search(BST->lchild, BST, p, data);
}else {
return search(BST->rchild, BST, p, data);
}
}
// 插入结点
void insert(BSTree *BST, int data){
BSTree p = NULL;
if(!search(*BST, NULL, &p, data)){ // 查找不成功
BSTree node = (BSTree)malloc(sizeof(BSTNode));
if(node == NULL){ // 内存分配失败
exit(0);
}
node->data = data;
node->lchild = node->rchild = NULL;
if(*BST == NULL){ // 第一个根节点
*BST = node;
}else if(data < p->data){
p->lchild = node;
}else{
p->rchild = node;
}
}
}
// 删除最小结点
int deleteMin(BSTree *BST){
BSTree p;
int data;
if(*BST == NULL) return -1;
if((*BST)->lchild == NULL){ //向左查找直到为空
p = *BST;
*BST = (*BST)->rchild;
data = p->data;
free(p);
return data;
}else{
return deleteMin(&((*BST)->lchild));
}
}
//删除结点
void deleteNode(BSTree *BST, int data){
BSTree p = NULL;
if(BST == NULL) return;
if(data < (*BST)->data){
deleteNode(&((*BST)->lchild), data);
}else if(data > (*BST)->data){
deleteNode(&((*BST)->rchild), data);
}else{
if((*BST)->lchild == NULL){ //左链为空,则右链继承
p = *BST;
*BST = (*BST)->rchild;
free(p);
}else if((*BST)->rchild == NULL){ //右链为空,则左链继承
p = *BST;
*BST = (*BST)->lchild;
free(p);
}else{//左右链都不为空,则删除右链的最小结点
(*BST)->data = deleteMin(&((*BST)->rchild));
}
}
}
//中序遍历
void inOrder(BSTree BST){
if(BST == NULL) return;
inOrder(BST->lchild);
printf("%d\t", BST->data);
inOrder(BST->rchild);
}
//测试
int main(){
BSTree BST = NULL;
int data[] = {4,2,9,5,12,11};
int num = sizeof(data)/sizeof(int);
for(int i = 0; i < num; i ++){
insert(&BST, data[i]);
}
inOrder(BST);
deleteNode(&BST,9);
inOrder(BST);
return 0;
}