堆排序分析及优化

堆排序,是利用堆结构进行排序,一般是利用最大堆,即根节点比左右两个子树的节点都大,具体算法步骤如下。

一、创建堆

首先将数组中的元素调整成堆,对应下面程序中的createHeap(List<Integer> list)方法。创建堆就是从树中最后一个内节点(下标为(n-1)/2)开始调整数组中元素的位置,使以这个内节点为根的子树满足堆的结构。即依次将以(n-1)/2、(n-1)/2-1、(n-1)/2-2、...、1、0为根的子树调整为堆。

创建堆主要用了shiftDown操作,对应下面的shiftDown(List<Integer> list,int parent,int end)方法。该操作是不断将小元素下调的过程,如果根元素小于左右两个子树的较大者,那么根元素就要跟这个较大者进行交换,直到到达叶子节点为止。siftDown操作每下降一层要比较两次:1)选择左右子树的较大者,2)将较大者跟父亲比较。下降的最大高度即为父节点的高度。由结论:高度为h的满二叉树的所有节点的高度和为n-h-1,高度从0开始,叶子节点高度为0,此结论可由数学归纳法证明,可知最坏情况的比较次数约为2(n-h-1),即创建堆的复杂度度为O(n)。

二、排序

当将数组调整成堆之后,由堆的定义可知,树的根就是最大的元素,这时我们可以将根删除,并将最后一个元素放到根的位置,然后将树重新调整为堆。重新调整为堆之后,根节点又为最大的元素,再删除,再调整,直到元素全部排序。(这里实际上是将最后一个元素和根元素交换,从此以后最后一个元素不在参与树的重新调整,即已经排好序的元素不再参与树的调整)。

shiftDown操作的时间复杂度为O(lgn),即树的高度,排序过程中一共进行了n-1的shiftDown操作,所以可以粗略的推断出堆排序的时间复杂度为O(nlgn)。空间复杂度为O(1)。

三、优化

堆中从根节点到叶节点的一条路径是有序的,最大堆是降序,我们在shiftDown操作时,实际上是在找根节点在某条路径上的一个插入位置,可以借鉴二分的思想,我们可以一次下降到当前高度h的一半的位置(在下降的过程中要将沿途的较大的子节点上移,这样在h/2高度形成空位),即h/2,再比较在一半高度h/2的节点与根节点的大小,如果比根节点大则继续寻找当前一半高度位置的元素即h/4,依次类推,如果当前高度的元素比根节点小,我们就引入shiftUp操作,即将根节点再上移,但由前面的分析可知,上移的次数是有限的,这样就将shiftDown的复杂度变为O(lglgn),堆排序的总体复杂度变为O(n*lglgn)。

下面是堆排序的Java实现,未经优化,优化的代码以后有时间给出。

import java.util.Arrays;
import java.util.List;
/*
 *创建最大堆,并进行排序
 */
public class HeapSort {

	public void swap(List<Integer> list, int m,int n){
		int temp = list.get(n);
		list.set(n, list.get(m));
		list.set(m,temp);
	}

	public List<Integer> createHeap(List<Integer> list){ //创建堆,从第一个非孩子结点开始调整,创建一个最大堆
		int n = list.size();
		for(int k = (n-1)/2;k >= 0;k--){
			shiftDown(list,k,n-1);
		}
		return list;
	}

	//将以parent为根节点的二叉树调整为堆
	public void shiftDown(List<Integer> list,int parent,int end){
		boolean flag = true;
		while(parent*2+1<=end && flag){ //如果存在左孩子就进行调整

			int lChild = parent*2+1;
			int max=0;
			if(lChild+1<=end){ //表示存在右孩子
				int rChild = lChild+1;
				max = list.get(lChild)>list.get(rChild)?lChild:rChild;
			}else{
				max = lChild;
			}
			if(list.get(max)>list.get(parent)){ //有子孩子比父亲大
				swap(list,max,parent);
				parent = max;
			}else{
				flag = false;//表示孩子都比父亲要小,不需要调整了
			}
		}
	}

	public void sort(List<Integer> heap){  //排序主过程
		int n = heap.size();
		int rmd = n-1;
		while(rmd>0){
			swap(heap,0,rmd);
			shiftDown(heap,0,rmd-1);
			rmd--;
		}
	}

	public static void main(String[] args) { //测试算法
		HeapSort hs = new HeapSort();
		List<Integer> list = null;
		list = Arrays.asList(3,0,23,6,5,43,23,566,8,5,34,23,667,34,123);
		hs.createHeap(list);
		hs.sort(list);
		for(int i=0;i<list.size();i++){
			System.out.print(list.get(i)+" ");
		}
	}
}
时间: 2024-10-08 18:15:35

堆排序分析及优化的相关文章

mysql性能优化-慢查询分析、优化索引和配置

一.优化概述 二.查询与索引优化分析 1性能瓶颈定位 Show命令 慢查询日志 explain分析查询 profiling分析查询 2索引及查询优化 三.配置优化 1)      max_connections 2)      back_log 3)      interactive_timeout 4)      key_buffer_size 5)      query_cache_size 6)      record_buffer_size 7)      read_rnd_buffer

linux服务器的性能分析与优化(十三)

[教程主题]:1.linux服务器的性能分析与优化 [主要内容] [1]影响Linux服务器性能的因素 操作系统级 Ø CPU 目前大部分CPU在同一时间只能运行一个线程,超线程的处理器可以在同一时间处理多个线程,因此可以利用超线程特性提高系统性能. 在linux系统下只有运行SMP内核才能支持超线程,但是安装的CPu数量越多,从超线程获得的性能提升越少. 另外linux内核会将多核的处理器当做多个单独的CPU来识别,例如,两个4核的CPU会被当成8个单个CPU,从性能角度讲,两个4核的CPU整

1.linux服务器的性能分析与优化

[教程主题]:1.linux服务器的性能分析与优化 [课程录制]: 创E [主要内容] [1]影响Linux服务器性能的因素 操作系统级 CPU 目前大部分CPU在同一时间只能运行一个线程,超线程的处理器可以在同一时间处理多个线程,因此可以利用超线程特性提高系统性能. 在linux系统下只有运行SMP内核才能支持超线程,但是安装的CPu数量越多,从超线程获得的性能提升越少. 另外linux内核会将多核的处理器当做多个单独的CPU来识别,例如,两个4核的CPU会被当成8个单个CPU,从性能角度讲,

新站做SEO的优势分析以及优化假象

很多做SEO的朋友对做新站很发愁,觉得新站没有收录,没有权重,没有外链,什么都没有,干干净净的白手起家很难做.其实换个角度去想,干干净净何尝不是一件好事.宝鸡SEO工作室橙橙同学为大家分析一下新站做SEO的优势分析以及优化假象." 我们都知道人的第一印象很重要.从第一次见面到短时间的相处,就能对一个人做一个简单的评价,这个评价可以说在其他人心里根深蒂固.那么,网站和百度蜘蛛的关系就像交友一样.我们要摸清这个规律,既然是交朋友,那么我们就给它一个好的第一印象.第一印象对人来说无非是穿衣打扮,个人素

《性能测试诊断分析与优化》学习总结(一)

我始终坚信,一本好书,可以改变人的一生,成功一定有方法,失败一定有原因,而我个人认为,失败的最大原因是学习不够.不断学习,活到老,学到老. 作为软件测试人员来说,或多或少都会对性能测试有点感兴趣,我个人认为,软件性能与软件功能的最大兴趣在于从用户体检的角度,感受软件的质量度量,如响应时间.准确性.成功率等. 性能测试的目标是通过制定性能测试策略.性能测试计划.执行性能测试,并对性能问题进行定位分析和优化.影响软件系统的性能主要因素包括:硬件设施.网络.操作系统.并发用户数.数据库数据量.中间件等

怎样粗略分析关键词优化难度

作为一个seo人员,判断某关键词优化难度是必备技能,而且跟个人经验有很大关系,下面列举的判断方法不足之处欢迎拍砖.1.域龄.虽说超过一年以上的站都可以说是老站,但是用一个纯新站在个把月超过它的某些中等难度的词还是很有信心的.网站年龄其实对优化起着很重要的作用,从收录和建立信任方面最能体现.尤其是一些域龄达到几年甚至十几年的,要做好打长期硬仗的准备.但作为个人站长来说用一个新站超过一两三年的网站还是没问题的,当然不是特难的词.2.网站域名是否包含了你要优化的关键词.这点有人觉得没必要,也许他们是从

【转】由浅入深探究mysql索引结构原理、性能分析与优化

摘要: 第一部分:基础知识 第二部分:MYISAM和INNODB索引结构 1.简单介绍B-tree B+ tree树 2.MyisAM索引结构 3.Annode索引结构 4.MyisAM索引与InnoDB索引相比较 第三部分:MYSQL优化 1.表数据类型选择 2.sql语句优化 (1)     最左前缀原则 (1.1)  能正确的利用索引 (1.2)  不能正确的利用索引 (1.3)  如果一个查询where子句中确实不需要password列,那就用“补洞”. (1.4)  like (2)

一:MySQL数据库的性能的影响分析及其优化

MySQL数据库的性能的影响分析及其优化 MySQL数据库的性能的影响 一. 服务器的硬件的限制 二. 服务器所使用的操作系统 三. 服务器的所配置的参数设置不同 四. 数据库存储引擎的选择 五. 数据库的参数配置的不同 六. (重点)数据库的结构的设计和SQL语句 1). 服务器的配置和设置(cpu和可用的内存的大小) 1.网络和I/O资源 2.cpu的主频和核心的数量的选择 (对于密集型的应用应该优先考虑主频高的cpu) (对于并发量大的应用优先考虑的多核的cpu) 3.磁盘的配置和选择 (

MYSQL数据库服务CPU高问题分析与优化

MySQL服务性能监控分析与优化是永恒的主题,做为性能测试人员有时也要站在DBA角度出发进行适当分析与优化,这也是性能测试人员能长期生存发展之路.而资源的使用监控分析才是性能故障分析的根本首要任务.在数据库服务器内部,如果执行的操作会严重受到内存.CPU或磁盘吞吐量中任何一个的影响,则可以将它视为瓶颈. 因此理解服务器如何运行,资源损耗在哪些方面对问题进行故障诊断是非常有价值有意义的活动,具体案例如下. 这些监控分析优化方法等细节我们在品课学院性能实战课堂中都会以实战方式进行实操性测试监控分析实