当前位置: 首页 > article >正文

103.【C语言】数据结构之建堆的时间复杂度分析

1.向下调整的时间复杂度

推导

设树高为h

39e01bdbb5cc491caf615aa7cf366d3d.png

发现如下规律

按最坏的情况考虑(即调整次数最多)

第1层,有eq?2%5E0个节点,最多向上调整h-1次

第2层,有eq?2%5E1个节点,最多向上调整h-2次

第3层,有eq?2%5E2个节点,最多向上调整h-3次

第4层,有eq?2%5E3个节点,最多向上调整h-4次

...

第h-1层,有eq?2%5E%7Bh-2%7D个节点,最多向上调整1次

第h层,有eq?2%5E%7Bh-1%7D个节点,最多向上调整0次

设T(N)为向下调整的总次数(每层节点数*这一层最坏向下调整多少次)

则有eq?T%28N%29%3D2%5E0*%28h-1%29+2%5E1*%28h-2%29+2%5E2*%28h-3%29+...+2%5E%7Bh-2%7D*1

对于T(N)的求和显然为等差*等比数列的求和,有两种做法:

等差*等比数列的求和

1.错位相减

eq?T%28N%29%3D2%5E0*%28h-1%29+2%5E1*%28h-2%29+2%5E2*%28h-3%29+...+2%5E%7Bh-2%7D*1

eq?2*T%28N%29%3D0+2%5E1*%28h-1%29+2%5E2*%28h-2%29+2%5E3*%28h-3%29+...+2%5E%7Bh-1%7D*1+0

所以eq?T%28N%29%3D2%5Eh-h-1

2.公式法

等差*等比数列的求和公式eq?S_n%3D%28An+B%29*q%5En-B,计算eq?S_1eq?S_2的值后再代入eq?S_n中即可求出eq?Aeq?B

eq?S_1%3D2%5E0*%28h-1%29,eq?S_2%3D2%5E0%28h-1%29+2%5E1*%28h-2%29

因此有

eq?%28A*1+B%29*2%5E1-B%3D2%5E0*%28h-1%29

eq?%28A*2+B%29*2%5E2-B%3D2%5E0*%28h-1%29+2%5E1*%28h-2%29

两式子联立可得eq?A%3D-2%5E%7Bh-1%7D%2CB%3D-2%5Eh,eq?S_n的n为h-1

所以eq?T%28N%29%3D2%5Eh-h-1

又因为eq?N%3D2%5Eh-1,因此eq?h%5Capprox%20%5Clog_2%20%28N+1%29

最终结果

所以eq?T%28N%29%3DN-%5Clog_2%20%28N+1%29%20%5Capprox%20N

2.向上调整的时间复杂度

推导

设树高为h

39e01bdbb5cc491caf615aa7cf366d3d.png

发现如下规律

按最坏的情况考虑(即调整次数最多)

第1层,有eq?2%5E0个节点,最多向上调整1次

第2层,有eq?2%5E1个节点,最多向上调整2次

第3层,有eq?2%5E2个节点,最多向上调整3次

第4层,有eq?2%5E3个节点,最多向上调整4次

...

第h-1层,有eq?2%5E%7Bh-2%7D个节点,最多向上调整h-1次

第h层,有eq?2%5E%7Bh-1%7D个节点,最多向上调整h次

设T(N)为向上调整的总次数(每层节点数*这一层最坏向上调整多少次)

则有eq?T%28N%29%3D2%5E0*1+2%5E1*2+2%5E2*3+...+2%5E%7Bh-1%7D*%28h-1%29+2%5Eh*h

计算后有eq?T%28N%29%3D%28h-1%29*2%5E%7Bh+1%7D+2

又因为eq?N%3D2%5Eh-1,因此eq?h%5Capprox%20%5Clog_2%20%28N+1%29%5Capprox%20%5Clog_2%20N

最终结果

所以eq?T%28N%29%3D%28%5Clog_2%20%28N+1%29-1%29%28N+1%29*2+2%20%5Capprox%20N*%5Clog_2%20N

3.对比

时间复杂度对比

结论:向上调整的时间复杂度为eq?O%28N*%5Clog%20_2%20N%29,向下调整的时间复杂度为eq?O%28N%29

对比:向上调整:节点个数多,调整次数多;向上调整:节点个数少,调整次数多;

图像对比

cdb28fa4184447e0bb10c63d666b09b9.png

3cd032ce190a4322a838cf9de8b9c172.png 

显然随着x越来越大,eq?xeq?x*%5Clog_2%20x的差距会越来越大

4.练习题

题目

求102.【C语言】数据结构之用堆对数组排序文章的HeapSort函数的while循环部分的时间复杂度

7cf7de489f934b16a3598f174753ea9f.png

 

分析

错误思路:因为while循环中有AdjustDown,所以为向下调整,时间复杂度为eq?O%28N%29

没有分析代码的执行过程导致出错

看二叉树的最后一层:有eq?2%5E%7Bh-1%7D个节点,每一个节点调整最多h次,因此属于eq?2%5E%7Bh-1%7D*h的求和计算,所以时间复杂度为eq?O%28N*%5Clog%20_2%20N%29

5.总结

用堆对数组进行排序,排升序建大堆的时间复杂度总为eq?O%28N*%5Clog%20_2%20N%29

对比

void HeapSort(int* arr, int n)
{
    //向上调整建堆时间复杂度为O(N*logN)
	for (int i = 1; i < n; i++)
	{
		AdjustUp(arr, i);
	}

    //排序的时间复杂度为O(N*logN)
	int end = n - 1;
	while (end > 0)
	{
		Swap(&arr[end], &arr[0]);
		AdjustDown(arr, end, 0);
		end--;
	}
}

void HeapSort(int* arr, int n)
{
    //向下调整建堆时间复杂度为O(N)
	for (int i = (n-1-1)/2; i >= 0; i--)
	{
		AdjustDown(a,n,i);
	}

    //排序的时间复杂度为O(N*logN)
	int end = n - 1;
	while (end > 0)
	{
		Swap(&arr[end], &arr[0]);
		AdjustDown(arr, end, 0);
		end--;
	}
}

 注意(n-1-1)/2这里把(n-1)视作整体

 

 


http://www.kler.cn/a/415091.html

相关文章:

  • Qt读写Usb设备的数据
  • Vue使用Mockjs插件实现模拟数据
  • MySQL - 表的增删查改
  • 【iOS】知乎日报总结
  • 蓝桥杯每日真题 - 第24天
  • 重学 Android 自定义 View 系列(八):星星评分控件(RatingBar)
  • Redis 字符串(String)
  • 前端开发项目中实现极佳的过渡动画效果
  • uniapp input只输入一个字符就自动失去焦点
  • Vue 3 学习文档(一)
  • ais_server 学习笔记
  • 列表上移下移功能实现
  • Qt Graphics View 绘图实例
  • C0034.在Ubuntu中安装的Qt路径
  • 构建现代Web应用:FastAPI、SQLModel、Vue 3与Axios的结合使用
  • linux系统中常用文件日常使用命令记录
  • 架构第十四章:zabbix-4
  • C++条件编译指令
  • Unity ShaderLab 实现交互地毯
  • 【zookeeper04】消息队列与微服务之zookeeper客户端访问
  • Linux基础项目包含(DNS,FTP,Samba)
  • 华为IPD流程学习之——深入解读123页华为IPD流程体系设计方法论PPT
  • STM32-- 看门狗--介绍、使用场景、失效场景
  • 2024健康大数据与智能医疗(ICHIH 2024)
  • LLM*:路径规划的大型语言模型增强增量启发式搜索
  • 第一篇:Admin.Net前端项目启动