堆排序(java)

目录

一、大顶堆

二、利用大顶堆排序

2.1  思路分析

2.2  大顶堆升序排序

2.3  小顶堆降序排序

三、总结


一、大顶堆

  • 必须是完全二叉树
  • 父节点的值必须大于其子节点的值

二、利用大顶堆排序

2.1  思路分析

      A:给定一个数组,将该数组看作一棵虚拟的完全二叉树;

      B:将该数组构造成一个大顶堆

          a:找到最后一个非叶子节点,比较该节点的值与其子节点的值,将父节点的值与最大值进行交换,完成局部大顶堆;

          b:局部大顶堆的按照"从右向左,从下至上"的原则进行,比如上面这个图,i=3时,完成局部大顶堆后,i应该变成2

               来完成上层右侧的局部大顶堆,以此类推,当i=0时,就完成最上层的大顶堆;

          c:就下图步骤3而言,9与4交换后,下面的大顶堆就不成立了,所以还需要重新构造;

      C:将大顶堆的最上面的值与最末尾的元素交换,也就是交换数组的首尾元素;

      D:交换结束后,末尾元素是最大值就不要动了,对数组的前n-1个元素,重新构造大顶堆

          a:这时候就不是找最后一个非叶子节点了,因为当前是除了堆顶外,其余子树都是局部大顶堆的形式,所以直接从

               从堆顶开始构造,重复步骤C,直到数组排序完成;

2.2  大顶堆升序排序

/**
 * 利用堆排序,实现数组的升序
 * @author Administrator
 * 
 * 分析
 *    A:给定一个数组,将该数组看作一棵虚拟的完全二叉树;
 *    B:定义adjustHeap方法,目的是从当前非叶子结点与其孩子中选出最大值;
 *    C:定义堆排序方法heapSort,首先构造大顶堆,然后将最大的元素与末尾的
 *      元素进行交换,除去末尾元素,重新构造大顶堆,反复执行。
 *      
 *
 */
public class HeapSort {
	public static void main(String[] args) {
		int[] arr = {4,6,8,5,9};
		heapSort(arr);
	}
	/**
	 * 这个方法用来构造局部大顶堆
	 * @param arr
	 * @param i
	 * @param length
	 */
	public static void adjustHeap(int[] arr,int i,int length) {
		int temp = arr[i];
		for(int k = i*2+1; k < length; k = i*2+1) {
			if(k+1 < length && arr[k] < arr[k+1]) {
				k++;
			}
			if(arr[k] > temp) {
				arr[i] = arr[k];
				i = k;
			} else {
				break;
			}
		}
		arr[i] = temp;
	}
	/**
	 * 这个方法用来实现堆排序
	 * @param arr 待排序的数组
	 */
	public static void heapSort(int[] arr) {
		int temp;
		for(int i = arr.length/2-1; i >= 0; i--) {
			adjustHeap(arr,i,arr.length);
		}
		for(int j = arr.length-1; j > 0; j--) {
			temp = arr[j];
			arr[j] = arr[0];
			arr[0] = temp;
			adjustHeap(arr,0,j);
		}
		System.out.println("数组:"+Arrays.toString(arr));
	}
}

2.3  小顶堆降序排序

  • 这个就是将构造大顶堆的大于号改成小于号就行了;

三、总结

  • 关于堆排序还未理解,尤其是代码,很神奇的感觉,关键在于i=k这条语句上;
  • 接下来尝试学习堆排序的不同实现方式来加深理解
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值