0
点赞
收藏
分享

微信扫一扫

查找: 二分 / B 树 / B+ 树

程序员知识圈 2021-09-30 阅读 48

1 查找 framework

1. 按 动 / 静 态 分:

静态查找
动态查找: 含 insert / delete

2. 按 `所查找 的 data structure` 分:

(1) 线性 structure
顺序查找
`二分查找`

(2) tree structure
`二叉 排序/搜索 树`
`B tree / B+ tree`

(3) 散列 structure
`hash_table`

2 顺序/线性 查找

适用: `线性表`
思路: `逐个比较`
// framework
// return index of the found elem or -1 if not found
int 
sequence_search(int* arr, int len, int target) 
{   
    for(int i = 0; i < len; ++i) 
    {   
        if (arr[i] == target) 
            return i;
    }
    
    return -1;
}
// an example
#include <cstdio>

// return index of the found elem or -1 if not found
int 
sequence_search(int* arr, int len, int target) 
{   
    for(int i = 0; i < len; ++i) 
    {   
        if (arr[i] == target) 
            return i;
    }
    
    return -1;
}

int main()
{
    int array[5] = { 1, 3, 5, 7, 9 };
    int array2[6] = { 1, 3, 5, 7, 9, 15};

    int found_index = sequence_search(array, 5, 7);
    if (found_index != -1)
        printf("found index: %d \n", found_index);

    found_index = sequence_search(array2, 6, 9);
    if (found_index != -1)
        printf("found index: %d \n", found_index);
}

3 二分查找

适用: `有序 顺序表`
思路: 
`找 给定 range 的 middle position, compare with given key:`
    == key => 找到
    <  key => 在 mid 左
    >  key => 在 mid 右

-> `update range -> 循环`
// framework
// return index of the found elem or -1 if not found
int 
binary_search(int* arr, int len, int target) 
{ 
    int left = 0, right = len - 1; 
    
    while(...) 
    { 
        int mid = left + (right - left) / 2; 

        if (arr[mid] == target) 
        { 
            ... 
        } 
        else if (arr[mid] < target) 
        { 
            left = ... 
        } 
        else if (arr[mid] > target) 
        { 
            right = ... 
        } 
    }
    
    return ...;
}
// an example
#include <cstdio>

// return index of the found elem or -1 if not found
int 
binary_search(int* arr, int len, int target) 
{ 
    int left = 0, right = len - 1; 
    
    while(left <= right) 
    { 
        int mid = left + (right - left) / 2; 

        if (arr[mid] == target) 
        { 
            return mid;
        } 
        else if (arr[mid] < target) 
        { 
            left = mid + 1;
        } 
        else if (arr[mid] > target) 
        { 
            right = mid - 1;
        } 
    }
    
    return -1;
}

int main()
{
    int array[5] = { 1, 3, 5, 7, 9 };
    int array2[6] = { 1, 3, 5, 7, 9, 15};

    int found_index = binary_search(array, 5, 7);
    if (found_index != -1)
        printf("found index: %d \n", found_index);

    found_index = binary_search(array2, 6, 9);
    if (found_index != -1)
        printf("found index: %d \n", found_index);
}

4 B 树

1. 概念
B 树 又称 `多路 平衡 查找树`

`B 树 的 阶: max_nodes_num`

node 有 n 个 key, 则 有 n + 1 个 subtree / pointer 域

性质:
(1) every node 有 <= m 个 子树
(2) 若 root is not leaf node, 则 有 >= 2 个 子树
(3) non-leaf node 有 >= ceil(m/2) 个 子树
(4) 有 n 个 key 的 non-leaf node structure:
n pointer_0 key_0 pointer_1 key_1 ... pointer_n-1 key_n-1 pointer_n

`key_0 < key_1 < ... < key_n-1`
`pointer_i 所指 子树 中 key < key_i`
`pointer_i+1 所指 子树 中 key > key_i`
i = 0,..., n-1

(5) `leaf node 都在 最底层, not include information`
-> 可 视为 外部 node

2. 高度 / 磁盘存取次数
not include leaf node 层

3. store -> 查找 思路

B 树 常 store 在 磁盘

=>

在 磁盘/B树 中 找 target node -> 找到 -> read node content to memory -> 二分查找 -> 找到 则 成功 -> 否则 -> 从 相应 pointer 所指 子树 中找

=> 

(1) B 树 中 找 node
(2) node 内 找 key

5 B+ 树: B 树 的 变形

1. 应用: 

数据库

2. 与 B 树 区别

`(1) node 有 n 个 key, 则 有 n 个 subtree / pointer 域`

而 B 树: node 有 n 个 key, 则 有 n + 1 个 subtree

(2) leaf node include information,
non-leaf node 只起 index/索引 作用

non-leaf node 只含: subtree 的 max_key & pointer
不含 key 对应 record 的 storage address

(3) leaf node 含 全部 key
=> non-leaf node 中 出现的 key 也会出现在 leaf node 中

而 B 树: `各 node 的 key 不重复`
B+ 树 通常有 2 个 head pointer:
1) pointer to root
2) pointer to leaf node whose key is minimux

=> `B+ 树 可进行 2 种查找`

`1) 从 min_key 开始的 顺序查找`

`2) 从 root 开始的 多路查找`

举报

相关推荐

B/B+树/B*树

B树,B+树

B树与B+树

B+树和B*树

B树和B+树

B-树,B+树

0 条评论