二分查找数(BST)

介绍

二分查找树是一种能够快速维护排序数值集的数据结构。

  1. 二叉树:因为每个节点最好有两个子节点
  2. 查找树:可以以O(log(n))的时间来查询值是否存在

二分查找树与普通二叉树的区别:

  1. 左子树的所有节点小于根节点
  2. 右子树的所有节点大于根节点
  3. 每个节点的所有子树也是二分查找树,满足上面两个条件

在这里插入图片描述
上图中,右边的二叉树并不是二分查找树,因为节点3的右子树包含小于节点3的值。
二分查找树可以进行两个基本操作

检查一个值是否在二分查找树

如果一个值小于根节点,那么值不会在右子树,需要在左子树上查找。如果一个值大于根节点,那么值不会在左子树,需要在右子树上查找。

If root == NULL 
    return NULL;
If number == root->data 
    return root->data;
If number < root->data 
    return search(root->left)
If number > root->data 
    return search(root->right)

在这里插入图片描述
如果值发现,我们返回这个值,以至在每个递归步骤中进行传递。如下图所示
在这里插入图片描述
如果值没有发现,那么最终达到一个叶子节点的左节点(NULL)或者右节点(NULL),然后在每个递归步骤进行传递。

在二分查找树中添加值

添加值到正确的位置上类似于查询,因为我们需要维护左子树小于根节点,右子树大于根节点。
依赖于值的大小,我们进入根节点的左子树或者右子树,当我们达到左节点或者右节点为NULL时,在这个位置添加一个新节点,表示这个值。

If node == NULL 
    return createNode(data)
if (data < node->data)
    node->left  = insert(node->left, data);
else if (data > node->data)
    node->right = insert(node->right, data);  
return node;

在这里插入图片描述
我们添加新节点,然而并不会改变二分查找树的其他部分。上面的代码是return node,如果是NULL,那么新创建的节点返回,添加到它的父节点上,除此之外,相同的节点被返回,并不会进行任何改变,直到返回到根节点。
在这里插入图片描述
实现方法:

#include<stdio.h>
#include<stdlib.h>
  
struct node
{
    int data;
    struct node* left;
    struct node* right;
};
struct node* createNode(value){
    struct node* newNode = malloc(sizeof(struct node));
    newNode->data = value;
    newNode->left = NULL;
    newNode->right = NULL;
    return newNode;
}
  
  
struct node* insert(struct node* root, int data)
{
    if (root == NULL) return createNode(data);
    if (data < root->data)
        root->left  = insert(root->left, data);
    else if (data > root->data)
        root->right = insert(root->right, data);   
 
    return root;
}
void inorder(struct node* root){
    if(root == NULL) return;
    inorder(root->left);
    printf("%d ->", root->data);
    inorder(root->right);
}
int main(){
    struct node *root = NULL;
    root = insert(root, 8);
    insert(root, 3);
    insert(root, 1);
    insert(root, 6);
    insert(root, 7);
    insert(root, 10);
    insert(root, 14);
    insert(root, 4);
    inorder(root);
}

输出为:

1 ->3 ->4 ->6 ->7 ->8 ->10 ->14 ->
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值