查找篇-二叉查找树

383 阅读2分钟

二叉查找树的优缺点

优点

二叉查找树的查找成功的平均时间复杂度为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;
}