常见排序算法之堆排序

1.简介

堆排序是指利用堆这种数据结构所设计的一种排序算法。

2.堆排序中大堆和小堆

大堆:根节点比子节点大
小堆:跟节点比子节点小

3.核心思想

采用大堆的数据结构为例子。
数组转完全二叉树,再把这个完全二叉树构成一个大堆,
将堆顶根节点和末尾节点互换。
把剩下的n-1个元素重新构造成大顶堆(最大值已经换到结尾处,我们不在去考虑,再找剩下n-1个数的最大值)
再次交换堆顶根节点和末尾节点…
重复操作直到最后只剩下一个数

4.步骤

(1).首先构造大堆
(2).把堆顶根节点和末尾节点互换
(3).剩下n-1和节点再次构造大堆
(4).重复操作

5.时间复杂度

nlogn ( n代表有n个数字要被构造为堆顶根节点,logn一棵树的高度,
最坏情况下,每个店都要冒一棵树的高度才能成为堆顶的根节点)

6.代码实现
public class HeapSort {
	/*
	    先说一下堆排序之前需要
	    构造的一些方法
	    (1) exchangeElements 数值交换方法
	  	(2)	maxHeap 子树构造大堆
	  	(3) buildMaxHeap 建立最大堆
	 
	  
	 */
	
	/**
	 * 堆排序方法开始
	 */
	public void heapSort(int[] a) {
		//数组非法性判断
		//只有一个数或者零个数就不用排序了
		//空数组也不用
		if (a == null || a.length <= 1) {
			return;
		}
		//(1).首先构造大堆
		buildMaxHeap(a);
		for(int i = a.length -1;i >= 1;i --) {
			//(2).把堆顶根节点和末尾节点互换
			exchangeElements(a,0,i);
			//(3).剩下n-1和节点再次构造大堆
			maxHeap(a,i,0);
		}
		
		
	}



	private void buildMaxHeap(int[] a) {
		//还是判断一下吧 ,万一被别的函数调用了呢
		if (a == null || a.length <= 1) {
			return;
		}
		//堆排序的优点体现在这里
		//只用遍历所有根节点就可以找出最大值
		int half = (a.length - 1)/2;
		//这里等于0也是要取的
		for(int i = half;i >= 0;i --) {
			//从最底层的根节点开始
			//调用maxHeap,子树排序
			maxHeap(a,a.length,i);
		}
		
	}

	/*
	 *length表示可控长度为,有多少节点要来构造大堆 
	 * i 表示我是以哪个节点为堆顶根节点来构造的
	 */

	private void maxHeap(int[] a, int length, int i) {
		if (a == null || a.length <= 1) {
			return;
		}
		//左子节点
		int left = i * 2 + 1;
		//右子节点
		int right =i * 2 + 2;
		//设置最大值下标
		//暂时设为i
		int largest = i;
		
		//left < length要放在a[left] > a[i] 前面
		//不然会报溢出异常
		if (left < length && a[left] > a[i] ) {
			largest = left;
		}
		
		if ( right <length && a[right] > a[largest] ) {
			largest = right;
		}
		//如果最大值的位置受到了变更
		if (largest != i) {
			//交换两者数据
			exchangeElements(a,largest,i);
			//再次子树构造大堆
			//主要是为了倒数第二排以上的根节点
			maxHeap(a, length, largest);
		}
	}
	
	
	
	private void exchangeElements(int[] a, int i, int j) {
		// TODO 自动生成的方法存根
		int temp = a[i];
		a[i] = a[j];
		a[j] = temp;
		
	}


	
	public static void main(String[] args) {
		int [] a = {3,4,6,1,2,10,19,87,45,26,47,15,99};
		HeapSort heapSort = new HeapSort();
		heapSort.heapSort(a);
		System.out.println(Arrays.toString(a));
	}
	
	
	
	
	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值