堆排序

1.堆

堆数据结构是一种数组对象,它可以被视为一科完全二叉树结构。它的特点是父节点的值大于(小于)两个子节点的值(分别称为大顶堆和小顶堆)。它常用于管理算法执行过程中的信息,应用场景包括堆排序,优先队列等。

2.完全二叉树

完全二叉树是效率很高的数据结构,堆是一种完全二叉树或者近似完全二叉树,所以效率极高,像十分常用的排序算法、Dijkstra算法、Prim算法等都要用堆才能优化,几乎每次都要考到的二叉排序树的效率也要借助平衡性来提高,而平衡性基于完全二叉树。

附上一份对堆排序讲解很经典的博文:http://blog.csdn.net/morewindows/article/details/6709644

堆排序:

import java.util.Scanner;

public class Main {

	// 存放/数据的数组
	static int[] array;
	// 数组长度
	static int length;

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);

		String string = sc.nextLine().trim();
		sc.close();

		String[] list = string.split(" ");

		length = list.length;

		array = new int[length];

		for (int i = 0; i < length; i++) {
			array[i] = Integer.parseInt(list[i]);
		}

		// 初始化数组:将该数组构造为最小堆
		init(length);

		sort();

		for (int num : array) {
			System.out.print(num + " ");
		}
		System.out.println();

	}

	/**
	 * 排序操作:将最小值/最小堆的最顶数据逐步交换至数组的尾部
	 */
	private static void sort() {

		for (int i = length; i > 1; i--) {
			// 将array[0]与array[i]交换,使得最小值位于数组末尾也即数组的i位置。
			swap(0, i - 1);
			nodeDown(0, i - 1);
		}

	}

	/**
	 * 将index结点下沉至适当位置
	 * 
	 * @param index
	 */
	private static void nodeDown(int index, int end) {

		int temp = array[index];
		int left = index * 2 + 1;

		while (left < end) {

			// 判断左右子节点大小
			if (left + 1 < end && array[left + 1] < array[left]) {
				left++;
			}

			// 如果左右子节点都比temp大的话结束下沉操作
			if (array[left] > temp) {
				break;
			}

			// 交换子节点和父节点
			swap(index, left);

			index = left;
			left = index * 2 + 1;

		}

	}

	/**
	 * 初始化该数组 使之成为最小堆
	 * 
	 * @param count
	 */
	private static void init(int count) {

		// 从最后一个结点的父节点开始往上逐个调整, 让较大的值沉下至合适位置
		for (int i = count / 2 - 1; i >= 0; i--) {
			nodeDown(i, length);
		}

	}

	/**
	 * 交换a结点和b结点的值
	 * 
	 * @param a
	 * @param b
	 */
	private static void swap(int a, int b) {

		int temp = array[a];
		array[a] = array[b];
		array[b] = temp;

	}

}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值