数据结构1

广义表

二叉树的基本特性

旋转二叉树

构造霍夫曼树(最优)

步骤:

  1. 初始化 :
    • 给定一组权值(通常是字符的频率),每个权值视为一个叶子节点。
    • 将所有权值按照大小顺序放入一个最小堆(或优先队列),确保可以每次取出最小的权值。
  2. 构造过程 :
    • 循环构建 :重复以下过程,直到堆中只剩下一个节点:
      1. 从堆中取出两个最小的节点(这两个节点具有最小的权值)。
      2. 创建一个新的节点,其权值是这两个节点的权值之和。这个新节点成为父节点,连接两个最小节点(作为它的左右子节点)。
      3. 将新节点插回堆中。
  3. 终止 :
    • 当堆中只剩一个节点时,说明霍夫曼树已经构造完毕。这个节点就是树的根节点。

线索二叉树

平衡二叉树

图

邻接矩阵

邻接表

图的遍历

拓扑排序

最小生成树

普利姆算法

普利姆算法 (Prim's Algorithm)是求解最小生成树(MST, Minimum Spanning Tree)的一种贪心算法。最小生成树是图中包含所有顶点且边权和最小的生成树。普利姆算法通过逐步扩展生成树来构造最小生成树,每次选择一条最小的边,连接树中的顶点与图中未连接的顶点。

普利姆算法的步骤:

  1. 初始化 :
    • 从图中任选一个顶点作为起始点(称为生成树的初始顶点)。
    • 设定一个标记集合,用来标记已加入生成树的顶点。
    • 初始化一个数组(或优先队列),用于记录从已加入生成树的顶点到其他顶点的最短边(权值最小的边)。
  2. 构建过程 :
    • 重复以下步骤直到所有顶点都加入生成树:
      1. 从标记集合外的顶点中,选择一条权值最小的边,将该边对应的顶点加入生成树。
      2. 更新与新加入顶点相连的边的权值,确保下次选择时会选取最小的边。
  3. 终止 :
    • 当所有顶点都被加入生成树时,算法终止。

示例:普利姆算法

假设有如下带权图:

复制代码

A

/ \

2 3

/ \

B-------C

1

图的邻接矩阵表示如下:

复制代码

A B C

A 0 2 3

B 2 0 1

C 3 1 0

步骤1:初始化
  • 选择顶点 A 作为起始顶点,生成树包含顶点 A。
  • 初始化一个数组记录从顶点 A 出发到其他顶点的最小边,边的权值为:
    • A -> B 权值为 2
    • A -> C 权值为 3
步骤2:构建生成树
  1. 从 A 开始,选择权值最小的边 A -> B,将顶点 B 加入生成树,生成树现在包含顶点 A 和 B。

    更新边权:

    • 从 B 出发的边为 B -> C,权值为 1。

    此时最小边为 B -> C。

  2. 选择边 B -> C,将顶点 C 加入生成树,生成树现在包含顶点 A、B 和 C。

    此时所有顶点都已被加入生成树,算法结束。

步骤3:结果

最终的最小生成树边为:

  • A -> B 权值 2
  • B -> C 权值 1

最小生成树的总权值为 2 + 1 = 3。

总结:

普利姆算法通过贪心策略逐步扩展生成树,每次选择当前生成树与未加入顶点之间的最小边。其时间复杂度通常为 O(E log V),其中 E 为图中的边数,V 为顶点数。对于稠密图(边数较多),普利姆算法比克鲁斯卡尔算法(Kruskal's Algorithm)更有效。

克鲁斯卡尔算法

克鲁斯卡尔算法 (Kruskal's Algorithm)是解决最小生成树(MST, Minimum Spanning Tree)问题的另一种经典贪心算法。它的核心思想是将图中的所有边按权重排序,然后逐步选择权重最小的边,确保不会形成环,最终形成一棵最小生成树。

克鲁斯卡尔算法的步骤:

  1. 初始化 :
    • 将图中的所有边按照权值升序排列。
    • 初始化每个顶点所在的集合(可以用并查集(Union-Find)来管理)。
    • 生成一个空的最小生成树。
  2. 构建过程 :
    • 遍历所有边,选择权值最小的边,判断它的两个端点是否属于同一个集合:
      1. 如果它们属于不同的集合,将这条边加入最小生成树,并合并这两个集合。
      2. 如果它们已经在同一个集合中,说明加入这条边会形成环,跳过这条边。
  3. 终止 :
    • 当最小生成树包含 V-1 条边(V 是图中的顶点数)时,算法结束。

示例:克鲁斯卡尔算法

假设有如下带权图:

复制代码

A

/ \

2 3

/ \

B-------C

1

图的邻接矩阵表示如下:

复制代码

A B C

A 0 2 3

B 2 0 1

C 3 1 0

步骤1:初始化
  • 将所有边按权值升序排列:
    • B -> C 权值 1
    • A -> B 权值 2
    • A -> C 权值 3
步骤2:构建生成树
  1. 选择边 B -> C(权值 1) :
    • B 和 C 还不在同一个集合中,加入生成树,合并集合。
  2. 选择边 A -> B(权值 2) :
    • A 和 B 也不在同一个集合中,加入生成树,合并集合。
  3. 选择边 A -> C(权值 3) :
    • A 和 C 已经在同一个集合中,加入这条边会形成环,所以跳过。
步骤3:结果

最小生成树的边为:

  • B -> C 权值 1
  • A -> B 权值 2

最小生成树的总权值为 1 + 2 = 3。

并查集(Union-Find)

克鲁斯卡尔算法依赖于并查集(Union-Find)来有效地管理和合并不同的集合。并查集是一种用于处理集合合并和查询问题的数据结构,支持两个主要操作:

  • Find:查找元素所在的集合。
  • Union:合并两个集合。

并查集的优化:

  • 路径压缩:在查找操作中,将查询路径上的所有节点直接连接到根节点,降低树的高度,从而加速后续的查询操作。
  • 按秩合并:在合并两个集合时,总是将较小的树合并到较大的树上,避免树的高度过大。

总结:

克鲁斯卡尔算法通过贪心策略,从图中选择权值最小的边并确保不形成环,直到构建出最小生成树。它的时间复杂度是 O(E log E),其中 E 是图中的边数。对于稀疏图(边数较少),克鲁斯卡尔算法通常比普利姆算法更加高效。

相关推荐
敲代码的苦1322 分钟前
头歌数据结构-排序的实现及其应用
数据结构
有同事要进步1 小时前
Leecode第68题:x的平方根
java·数据结构·算法
Pniubi1 小时前
HashMap扩容全流程
java·开发语言·数据结构
by209991 天前
哈希表——快速找到数据:冲突、删除与扩容的实现
数据结构·c++·哈希算法·散列表
Code_Solitude1 天前
c语言:关于qsoet函数知识点
c语言·数据结构·算法
Pniubi1 天前
快速排序(力扣基础)(递归)
java·数据结构·算法
inrichtt1 天前
第八课时:SPI总线揭秘:四线全双工通信的奥
c语言·数据结构·stm32·单片机·嵌入式硬件
HPtiger1 天前
数据结构——选择排序
数据结构·算法·排序算法
丑梨数据1 天前
信创环境里跑文档工具:格式兼容与本地合规的几个坑
数据结构·人工智能·算法·决策树·排序算法
烂蜻蜓1 天前
Pandas入门教程(四):Series数据结构——创建、索引与常用方法
数据结构·pandas