#各种树

1.二叉树

特殊的二叉树有:

               1                                1
            /     \                          /      \
          1        1                        1         1
       /    \    /    \                  /     \
       1    1    1     1               1         1
        满二叉树                              完全二叉树

从图就可看出,满二叉树是一个绝对的三角形,而完全二叉树是一个右下角可能有缺口的三角形。

二叉树的增、查都很easy。删的话分三种情况:

①叶子节点的删操作,easy,不解释;

②仅有左子树或仅有右子树节点的删操作,easy,不解释;

③既有左子树,又有右子树节点的删操作。需要找到前驱(左子树中最大的数)或者后继(右子树中最小的数)来替换被删的该节点。

关于二叉树的遍历,只要记住三句话:

前序遍历:根、左、右;

中序遍历:左、根、右;

后序遍历:左、右、根。

关键:这里的前中后是以根为参照对象而言。

做道题感受下:

前序遍历结果:ABDGHCEIF

中序遍历结果:GDHBAEICF

后序遍历结果:GHDBIEFCA

2.B树(即B-树)

①阶数M=max(儿子数)=max(关键字数)+1 ; 儿子数=指针数=子节点树=关键字数+1

②关键字数量限制:根节点[1,M-1]        非根非叶子节点[cell(M/2)-1,M-1]

③关键字集合遍布整棵树,任何关键字只出现一次,故搜索可能在非叶子节点结束

做一道练习题来消化一下:https://blog.csdn.net/li_canhui/article/details/85305147

题目:设定B-树的阶为5,用关键字序列{1,2,6,7,11,4,8,13,10,5,17,9,16,20,3,12,14,18,19,15}来构建一棵B-树。

答案:Key:一步一步来,就像往上爬楼梯

3.B+树

根B树有点类似,但是!淡化了很多概念:

①阶数M=max(儿子数) ; 儿子数=指针数=子节点树=关键字数

②关键字数量限制:根节点[1,M]        非根非叶子节点[cell(M/2),M]

③所有关键字都在叶子节点出现,关键字可能不只出现一次,故搜索一定在叶子节点结束

④须注意,非叶子节点里也可出现非关键字!

用一个例子(取自 谢兴生《高级数据库》)感受一下B+树增、删操作:

原树长这样:

插入8后,长这样:

删除19,2;再删除24后长这样:

至于B+树的构建过程,比较复杂,先不做描述,可参考   谢兴生《高级数据库》,158页。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
首先,需要实现各种搜索,如二叉搜索、AVL、红黑、B、B+等。可以使用各种编程语言来实现,比如C++、Java、Python等。以下以C++为例。 接下来,需要实现插入、删除、查找等操作,并统计其时间复杂度和执行时间。可以使用C++的chrono库来计时,代码如下: ```c++ #include <chrono> #include <iostream> #include "bst.h" // 自己实现的二叉搜索头文件 #include "avl.h" // 自己实现的AVL头文件 #include "rbt.h" // 自己实现的红黑头文件 #include "btree.h" // 自己实现的B头文件 #include "bplustree.h" // 自己实现的B+头文件 using namespace std; using namespace chrono; int main() { int n = 1000000; // 插入元素个数 int m = 10000; // 查询元素个数 int max_val = 1000000000; // 元素最大值 // 二叉搜索 BST bst; auto start = high_resolution_clock::now(); for (int i = 0; i < n; i++) { bst.insert(rand() % max_val); } auto stop = high_resolution_clock::now(); auto duration = duration_cast<milliseconds>(stop - start); cout << "BST insert " << n << " elements costs " << duration.count() << " ms" << endl; start = high_resolution_clock::now(); for (int i = 0; i < m; i++) { bst.find(rand() % max_val); } stop = high_resolution_clock::now(); duration = duration_cast<milliseconds>(stop - start); cout << "BST find " << m << " elements costs " << duration.count() << " ms" << endl; // AVL AVL avl; start = high_resolution_clock::now(); for (int i = 0; i < n; i++) { avl.insert(rand() % max_val); } stop = high_resolution_clock::now(); duration = duration_cast<milliseconds>(stop - start); cout << "AVL insert " << n << " elements costs " << duration.count() << " ms" << endl; start = high_resolution_clock::now(); for (int i = 0; i < m; i++) { avl.find(rand() % max_val); } stop = high_resolution_clock::now(); duration = duration_cast<milliseconds>(stop - start); cout << "AVL find " << m << " elements costs " << duration.count() << " ms" << endl; // 红黑 RBT rbt; start = high_resolution_clock::now(); for (int i = 0; i < n; i++) { rbt.insert(rand() % max_val); } stop = high_resolution_clock::now(); duration = duration_cast<milliseconds>(stop - start); cout << "RBT insert " << n << " elements costs " << duration.count() << " ms" << endl; start = high_resolution_clock::now(); for (int i = 0; i < m; i++) { rbt.find(rand() % max_val); } stop = high_resolution_clock::now(); duration = duration_cast<milliseconds>(stop - start); cout << "RBT find " << m << " elements costs " << duration.count() << " ms" << endl; // B BTree btree(5); // 阶数为5的B start = high_resolution_clock::now(); for (int i = 0; i < n; i++) { btree.insert(rand() % max_val); } stop = high_resolution_clock::now(); duration = duration_cast<milliseconds>(stop - start); cout << "BTree insert " << n << " elements costs " << duration.count() << " ms" << endl; start = high_resolution_clock::now(); for (int i = 0; i < m; i++) { btree.find(rand() % max_val); } stop = high_resolution_clock::now(); duration = duration_cast<milliseconds>(stop - start); cout << "BTree find " << m << " elements costs " << duration.count() << " ms" << endl; // B+ BPlusTree bplustree(5); // 阶数为5的B+ start = high_resolution_clock::now(); for (int i = 0; i < n; i++) { bplustree.insert(rand() % max_val); } stop = high_resolution_clock::now(); duration = duration_cast<milliseconds>(stop - start); cout << "BPlusTree insert " << n << " elements costs " << duration.count() << " ms" << endl; start = high_resolution_clock::now(); for (int i = 0; i < m; i++) { bplustree.find(rand() % max_val); } stop = high_resolution_clock::now(); duration = duration_cast<milliseconds>(stop - start); cout << "BPlusTree find " << m << " elements costs " << duration.count() << " ms" << endl; return 0; } ``` 以上代码可以同时测试各种搜索的插入和查找操作的效率。 最后,将代码编译运行即可获得各种搜索的效率比较结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值