小学生必知必会——(BSTREE)二叉搜索树

小学生必知必会——(BSTREE)二叉搜索树

二叉排序树(Binary Sort Tree,简称 BST )又叫二叉查找树和二叉搜索树。最少能以O(logn)查找删除元素。

性质:

二叉搜索树的本质是一颗二叉树,根节点的左孩子小于根节点,右孩子大于根节点,并且中序遍历是有序的。

插入节点

insert_Node 插入一个key如果树为空(NULL)key申请的节点为根节点。如果key小于根节点(root)的值key插入到左孩子节点,如果key大于根节点(root)的值key插入右孩子节点,否则遇到了重复节点直接返回。

前置节点

找到根节点的左孩子,在一直向右遍历到叶子节点就是根节点的前置节点。(根节点不是只有一个,对当前节点进行操作就可以暂时把当前节点当成根节点)

删除节点

情况(1) 度为0或1的节点

如果度为1,删除该节点,返回唯一孩子节点代替父节点

度为0直接删除,返回NULL

情况(2)度为2的节点

找到前置节点,将前置节点的值覆盖掉当前节点的值,删除前置节点退化到了情况(1)。

遍历二叉树

中序遍历

当前节点为空(NULL)空操作原路返回。

如果左子树不为NULL 中序遍历左子树

访问根节点

如果右子树不为NULL 中序遍历右子树

前序遍历

当前节点为空(NULL)空操作原路返回。

访问跟节点

如果左子树不为NULL 前序遍历左子树

如果右子树不为NULL 前序遍历右子树

释放二叉树

同上 将printf改成free释放节点

/*************************************************************************
	> File Name: BS_Tree.c
 ************************************************************************/

#include<stdio.h>
#include<stdlib.h>

typedef struct Node 
{
    int key;
    struct Node *lchild, *rchild;
}Node;

Node *getNewNode(int key)
{
    Node *p = (Node *)malloc(sizeof(Node));
    p->key = key;
    p->lchild = p->rchild = NULL;
     
    return p;
}
void inorder(Node *root);
void Preorder(Node *root);

Node *insert_Node(Node *root, int key)
{
    if(root == NULL) return getNewNode(key);
    if(root->key == key) return root;
    if(root->key > key)
    {
        root->lchild = insert_Node(root->lchild, key);
    }
    else
    {
        root->rchild = insert_Node(root->rchild, key);
    }
    return root;
}

Node *predecessor(Node *root)
{
    Node *temp = root->lchild;
    while(temp != NULL) temp = temp->rchild;

    return temp;
}

Node *earse_Node(Node *root, int key)
{
    if(root == NULL) return NULL;

    if(root->key > key)
    {
        root->lchild = earse_Node(root->lchild, key);
    }
    else if(root->key < key)
    {
        root->rchild = earse_Node(root->rchild, key);
    }
    else
    {
        if(root->lchild == NULL || root->rchild == NULL)
        {
            Node *temp = root->lchild != NULL ? root->lchild : root->rchild;
            free(root);
            return temp;
        }
        else
        {
            Node *temp = predecessor(root); 
            root->key = temp->key;
            root->lchild = earse_Node(root->lchild, temp->key);
        }
    }
    return root;
}

void clear(Node *root)
{
    if(root == NULL) return ;
    if(root->lchild != NULL) clear(root->lchild);
    if(root->rchild != NULL) clear(root->rchild);
    free(root);

    return ;
}

void Preorder(Node *root)
{
    if(root == NULL) return ;
    printf("%d ", root->key);
    if(root->lchild != NULL) inorder(root->lchild);
    if(root->rchild != NULL) inorder(root->rchild);

    return ;
}

void inorder(Node *root)
{
    if(root == NULL) return ;
    if(root->lchild != NULL) inorder(root->lchild);
    printf("%d ", root->key);
    if(root->rchild != NULL) inorder(root->rchild);

    return ;
}

int main()
{
    Node *root = NULL;
    #define MAX_INT 20
    int op = 0;
    int key = 0;
    int i; 
    for(i = 0; i < MAX_INT; i++)
    {
        scanf("%d %d", &op, &key);
        switch(op)
        {
            case 1 : root = insert_Node(root, key); break;
            case 2 : root = earse_Node(root, key); break; 
            default : break;
        }
        inorder(root);
    }
    clear(root);    
    return 0;
}

总结:二叉搜索树最好情况是以O(logn)的时间复杂度来插入删除元素,如果插入的都属有序的元素那么该复杂度还是O(n)级别,此时这颗二叉树就会退化成链表,具体如何才能解决这种情况,过一阵会更新平衡二叉排序树(AVL_TREE)。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值