2021-05-24 二项堆的实现和分析(含可视化Qt)

list

  • 项目目录
  • 项目描述
  • 基本功能实现
  • 数据生成器测试
  • 时间复杂度理论推导
  • 时间复杂度实验验证
    • 如何设计实验
    • 如何获取数据
    • 如何绘制图像
  • 和其他数据结构类型的比较
    • 和普通数组的比较 v e c t o r vector vector
    • 和链表list的比较 l i s t list list
    • 和和普通堆的比较 p r i o r i t y _ q u e u e priority\_queue priority_queue
    • 和左高树的比较
    • 和红黑树的比较 m a p map map and $set $
    • 和哈希的比较 h a s h hash hash
  • 界面的制作

list

二项堆项目目录
二项堆命令行版(主要包含相关效率分析实验)
│  list.txt  //项目目录
│  binaryHeap.h
|  binaryHeap.cpp
│  list.txt  //项目目录
│  vislization.cpp
|  main.cpp //主函数文件
│  in.txt
│  graph.dot
│  graph.jpg
    

二项堆Qt版本(可视化操作)
|    binaryheap.cpp
|   binaryheap.h
|   binaryHeap.pro
|    binaryHeap.pro.user
|    list.txt
|    main.cpp
|    mainwindow.cpp
|    mainwindow.h
|    mainwindow.ui
|    visualization.cpp
|    visualization.h

项目描述

二项堆的实现和分析

问题描述:

认识二项树、二项堆数据结构,并能应用该结构解决实际问题。

二项堆是二项树的集合,二项树是一种递归定义的有序树。它的递归定义如下:

(1) 二项树B0只有一个结点;

(2) 二项树Bk由两棵二项树B(k-1)组成的,其中一棵树是另一棵树根的最左孩子。
在这里插入图片描述

二项树具有如下的性质:

  1. 对于树Bk,该树含有2k个节点;

  2. 树的高度是k;

  3. 在深度为i中含有 节点,其中i = 0, 1,2 … , k;

二项堆H是具备如下性质的二项树的集合

  1. H中的每个二项树遵循最小堆性质;

  2. 对于任意的整数k的话,H中最多有一个二项树的根的度数是k;

基本要求:

① 设计二项堆ADT,其上的基本操作包括:

Make Heap ():初始化一个空堆;

Find-Min():返回一个指向最小关键字元素的指针

Union(H):与堆H进行合并,合并后的结果保存在当前堆,H变为空

Insert(x):插入元素x

Extract-Min():从堆中删除最小关键字元素,并返回指向删除元素的指针。

Decrease Key (x,k):将元素x的关键字赋予新值k;

Delete(x):从堆中删除元素x;

② 实现二项堆ADT,包括实现二项堆的存储结构以及其上的基本操作,并分析基本操作的时间复杂性。

③ 实现二项堆ADT的基本操作展示。
在这里插入图片描述

数据生成器

数据操作格式

  1. 第1行:初始化元素数n,操作个数m

  2. 第2~n+1行:n个元素的大小

  3. 接下来m行:<op,value1,value2=NULL> 格式

op:操作类型

value1,value2:大小

<insert,value> 添加

<erase,value> 删除元素

<erasemin> 删除最小

<update,old,new>更新元素

特别注意:操作中删除操作和插入操作的数量关系

关于理论分析

时间复杂度的推导

应用贪心思想

二项堆各种操作的时间复杂度如下所示:

操作名称操作时间复杂度
合并 O ( l o g n ) O(logn) O(logn)
插入 O ( l o g n ) O(logn) O(logn)
删除 O ( l o g n ) O(logn) O(logn)
删除最小 O ( l o g n ) O(logn) O(logn)
减小元素大小 O ( l o g n ) O(logn) O(logn)
增大元素大小 O ( l o g n ) O(logn) O(logn)
查找最小 O ( l o g n ) O(logn) O(logn)

具体推导如下所示:

根据二项堆的定义可知,二项堆满足一下两条性质

1. 每棵二项树都满足最小堆性质。即,父节点的关键字 <= 它的孩子的关键字。

2. 不能有两棵或以上的二项树具有相同的度数(包括度数为0)。换句话说,具有度数k的二项树有0个或1个。

3. 二项堆是二项树的集合,且二项树B0只含有一个点(零图)

4. 二项树的递归定义: B k = 2 B k − 1 B_k=2B_{k-1} Bk=2Bk1

5.二项堆中的任意两颗树的度数(即树中的节点个数)都不相同二项堆的最重要性质

合并操作的时间复杂度

不妨设两个二项堆中含 n 1 n_1 n1 n 2 n_2 n2和节点,且分别由 k 1 k_1 k1 k 2 k_2 k2个二项树构成。

根据二项堆的性质4可知,
二 项 树 B k 的 节 点 个 数 满 足 B k = 2 k ( k = 0 , 1 , 2 , 3... ) 二项树B_k的节点个数满足B_k=2^k (k=0,1,2,3...)\\ BkBk=2k(k=0,1,2,3...)
由于在合并两个二项堆的时候,首先应将两个二项堆的跟链表进行归并,即完成有序链表的归并,因此第一步归并操作的时间复杂度为
O ( 跟 链 表 长 度 1 + 跟 链 表 长 度 2 ) O(跟链表长度1+跟链表长度2) O(1+2)
因此,当跟链表长度最大时,归并的时间复杂度最大。

以第一个二项堆为例,二项堆中的节点个数满足如下等式
二 项 堆 的 总 节 点 数 = 所 有 二 项 树 的 节 点 数 之 和 二项堆的总节点数=所有二项树的节点数之和 =
因此,带入通项公式 B k = 2 B k − 1 B_k=2B_{k-1} Bk=2Bk1
n 1 = 2 x 1 + 2 x 2 + 2 x 3 + 2 x 4 + . . . n_1=2^{x_1}+2^{x_2}+2^{x_3}+2^{x_4}+... n1=2x1+2x2+2x3+2x4+...
由于二项堆中的任意两颗树的度数(即树中的节点个数)都不相同因此
x 1 ! = x 2 ! = x 3 ! = x 4 ! = . . . ! = x k 1 x_1!=x_2!=x_3!=x_4!=...!=x_{k_1} x1!=x2!=x3!=x4!=...!=xk1

当总结点数 n 1 n_1 n1给定时, x 1 , x 2 , x 3 , x 4 x_1,x_2,x_3,x_4 x1,x2,x3,x4顺次从0开始时,求和最小(否则反证法可与推出更小的)。因此当满足
n 1 = ∑ i = 0 k 1 2 i n_1=\sum\limits_{i=0}^{k1}{2^i} n1=i=0k12i

时, k 1 k_1 k1达到最小。

由等比数列求和公式可得,
n 1 = B 0 ( 1 − 2 k 1 ) 1 − 2 n_1=\frac{B_0(1-2^{k_1})}{1-2} n1=12B0(12k1)
化简可得
k 1 = l o g ( n 1 + 1 ) k_1=log(n_1+1) k1=log(n1+1)
k 1 k_1 k1最大为 l o g ( n 1 + 1 ) log(n_1+1) log(n1+1).因此对于合并两个二项堆的时间复杂度为 O ( l o g ( n 1 + 1 ) ) + O ( l o g ( n 2 + 1 ) ) = O ( l o g n ) O(log(n_1+1))+O(log(n_2+1))=O(logn) O(log(n1+1))+O(log(n2+1))=O(logn)

关于合并操作时间复杂度的细节

假设 n 1 + n 2 = n n_1+n_2=n n1+n2=n,则
l o g ( n 1 + 1 ) + l o g ( n 2 + 1 ) = l o g ( ( n 1 + 1 ) × ( n 2 + 1 ) ) log(n_1+1)+log(n_2+1)=log((n_1+1)\times (n_2+1))\\ log(n1+1)+log(n2+1)=log((n1+1)×(n2+1))
f ( n 1 , n 2 ) = ( n 1 + 1 ) × ( n 2 + 1 ) f(n_1,n_2)=(n_1+1)\times (n_2+1) f(n1,n2)=(n1+1)×(n2+1) n 1 + n 2 = n n_1+n_2=n n1+n2=n,则由均值不等式可得
f ( n 1 , n 2 ) ≤ ( n 1 + n 2 + 2 2 ) 2 f(n_1,n_2)\leq (\frac{n_1+n_2+2}{2})^2 f(n1,n2)(2n1+n2+2)2
当且仅当 n 1 + 1 = n 2 + 1 n_1+1=n_2+1 n1+1=n2+1时等号成立。也就是说合并两个大小相近的二项堆所需时间更多

也可以用拉格朗日乘数法对多元函数的条件极值求导,侧面反应外排序中每一个顺串的大小尽量相同时,时间复杂度最小)

使用拉格朗日乘数法进行严格的推导(避免基本不等式等号能否取到的判断)
在这里插入图片描述
在这里插入图片描述

插入操作时间复杂度

相当于原来的二项堆和一个只含一个元素的二项堆进行合并,带入上述公式可得,时间复杂度为 O ( l o g ( 1 + 1 ) ) + O ( l o g ( n + 1 ) ) = O ( l o g n ) O(log(1+1))+O(log(n+1))=O(logn) O(log(1+1))+O(log(n+1))=O(logn)

删除操作时间复杂度

关于界面的绘制

关于各种数据结构的比较

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sentry-X

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值