各种各样的树

本文详细介绍了树型数据结构的基础概念,包括二叉查找树、B树和B+树的定义、特点及应用。重点讨论了它们在文件系统和数据库中的实现,特别强调了B+树相较于B树的优势,包括叶节点的数据存储、关键码的存储方式以及对文件操作速度的影响。

最近对存储/更新/检索 比较感兴趣,树是传统数据库实现索引的主要方式,所以抽空整理学习一下。

 

最基本的二叉查找树: http://zh.wikipedia.org/wiki/%E4%BA%8C%E5%85%83%E6%90%9C%E5%B0%8B%E6%A8%B9

左右节点,内部节点和叶子节点都会存储数据;实现简单,遍历方便,平均高度是logN,但可能退化成N。

实际情况一般使用BST的变种,比如红黑树,AVL树,他们可以保证logN的高度。STL中set,map等数据结构使用的是就红黑树。

红黑树: http://zh.wikipedia.org/wiki/%E7%BA%A2%E9%BB%91%E6%A0%91

 

B树:http://en.wikipedia.org/wiki/B-tree

平衡树,但是每个节点的子节点可能会多于2个,子节点和叶子节点都可能存储数据,多用在文件系统和数据库中;

 

B+树:http://en.wikipedia.org/wiki/B+_tree

B树的变种,只在叶子节点中存储数据。

 

B树和B+树的些微区别

实现树型目录结构文件系统,常采用二叉树,其中每个节点都有父指针,子指针和兄弟指针,其中子指针指向该目录下的第一个子节点,而该子节点的父指针则指向 它的上级目录。目录下各子节点用兄弟指针连接起来。大型文件系统一般采用B+树实现,而不采用B树,这时因为:在B树中,分支节点和叶子节点均保存记录的 关键码和记录的指针;在B+树中,分支节点只保存记录关键码的复制,无记录指针,所有记录都集中在叶节点一层,并且叶节点可以构成一维线性表,便于连续访 问和范围查询。由于在B树的叶子节点中直接就包含记录,导致了叶节点能存放的SearchKey数目减少,同样大的文件相应的需要的节点数目就增多了,树 的高度也较B+树深了很多。对于同样阶的B树和B+树,B+树的树高和平均检索长度均大于B树(因为B+树必须检索到叶节点一层);但实际检索过程中,最 耗时间的是I/O,也就是访盘次数越少越好。B+树的分支节点无记录指针,同样一个盘块可以存放的关键码数就更多,所以虽然平均检索长度大,但访盘次数反 而少,文件操作的速度也就比B树快。

 

图(Graph)是一种用于表示实体之间复杂关系的数据结构,由一组节点(顶点)和连接这些节点的边组成,可用于表示社交网络、交通网络、网络路由等场景[^1]。 ### 图 图的存储方式有邻接矩阵和邻接表。邻接表类AdjGraph的设计代码如下: ```cpp template<class i> class AdjGraph //图邻接表类 { public: HNode adjlist[MAXV]; //头结点数组 int n, e; AdjGraph() { for (int i = 0; i < MAXV; i++) { adjlist[i].firstarc = NULL; } } ~AdjGraph() { ArcNode* pre, * p; for (int i = 0; i < n; i++) //遍历所有头结点 { pre = adjlist[i].firstarc; //用一个ArcNode指针指向头结点的fitst区域 if (pre != NULL) //若不为空 { p = pre->nextarc; //则用另外一个ArcNode指针指向头结点的下一个结点 while (p != NULL) //释放过程,循环删除 { delete pre; pre = p; p = p->nextarc; //两个指针同步后移 } delete pre; } } } void CreateAdjGraph(int a[][MAXV], int n, int e); //通过a,n,e来建立图的邻接表 void DispAdjGraph(); //输出图的邻接表 int Degree1(AdjGraph* G, int v); //计算无向图某个顶点的度,v为顶点名称 i Degree2(AdjGraph& G, int v); //计算有向图某个顶点的出度和入度,v为顶点名称 }; ``` 图的基本运算可在邻接表中实现,包括图的遍历(深度优先遍历(DFS)、广度优先遍历(BFS))、连接分量和生成等操作[^3][^4]。 ### 生成 生成是连通图的极小连通子图,含有图中全部的n个顶点,恰好只有n - 1条边。最小生成(Minimum Spanning Tree,简称MST)也称为最小权重生成、最小支撑,是所有生成中总权值最小的那棵,适用于有权的连通图。在许多领域有重要作用,例如在n个城市之间铺设光缆,使它们都可以通信,要使铺设光缆的总费用最低,就可以利用最小生成的算法来解决。求最小生成有两个经典算法:Prim(普里姆算法)和Kruskal(克鲁斯科尔算法)。并且从任意一点出发最小生成的最小代价总和都相等,完整代码可参考:https://github.com/hitskyer/course/blob/master/dataAlgorithm/chenmingming/graph/arrayGraph.cpp [^2][^5]。 ### 链 引用中未提及Graph库中关于链结构的相关内容,一般来说,链在数据结构中可以理解为链表,是一种线性的数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。在图的应用中,可能会使用到链表来存储图的邻接表等信息。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值