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;
}
}