您的位置:首页 > 编程语言 > Java开发

Java排序算法9:堆排序

2014-04-13 20:25 211 查看
一.思想:

先将初始序列构造成一个大根堆(或者小根堆),此堆为初始无序区。再将最大记录R[1]与无序区的最后一个记录R
交换,由此可以得到新的无序区R[1....n-1]和有序区R
。由于交换之后新的根R[1]可能不满足大根堆的性质,故将当前无序区R[1...n-1]再次调整为堆,然后再次将R[1]与R[n-1]交换,依次类推。

二.图解:

给定一个整形数组num[]={16,7,3,20,17,8},对其进行堆排序。首先根据该数组元素构建一个完全二叉树,得到


然后需要构造初始堆,则从最后一个非叶节点开始调整,调整过程如下:









这样就得到了初始堆。

即每次调整都是从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换(交换之后可能造成被交换的孩子节点不满足堆的性质,因此每次交换之后要重新对被交换的孩子节点进行调整)。有了初始堆之后就可以进行排序了。


此时3位于堆顶不满堆的性质,则需调整继续调整




















这样整个区间便已经有序了。

三.实现代码:

public class HeapSort {

public static void main(String[] args) {
int[] data5 = new int[] { 5, 3, 6, 2, 1, 9, 4, 8, 7 };
print(data5);
heapSort(data5);
System.out.println("排序后的数组:");
print(data5);
}

public static void swap(int[] data, int i, int j) {
if (i == j) {
return;
}
data[i] = data[i] + data[j];
data[j] = data[i] - data[j];
data[i] = data[i] - data[j];
}

public static void heapSort(int[] data) {
for (int i = 0; i < data.length; i++) {
createMaxdHeap(data, data.length - 1 - i);
swap(data, 0, data.length - 1 - i);
}
}

public static void createMaxdHeap(int[] data, int lastIndex) {
for (int i = (lastIndex - 1) / 2; i >= 0; i--) {
// 保存当前正在判断的节点
int k = i;
// 若当前节点的子节点存在
while (2 * k + 1 <= lastIndex) {
// biggerIndex总是记录较大节点的值,先赋值为当前判断节点的左子节点
int biggerIndex = 2 * k + 1;
if (biggerIndex < lastIndex) {
// 若右子节点存在,否则此时biggerIndex应该等于 lastIndex
if (data[biggerIndex] < data[biggerIndex + 1]) {
// 若右子节点值比左子节点值大,则biggerIndex记录的是右子节点的值
biggerIndex++;
}
}
if (data[k] < data[biggerIndex]) {
// 若当前节点值比子节点最大值小,则交换2者得值,交换后将biggerIndex值赋值给k
swap(data, k, biggerIndex);
k = biggerIndex;
} else {
break;
}
}
}
}

public static void print(int[] data) {
for (int i = 0; i < data.length; i++) {
System.out.print(data[i] + "\t");
}
System.out.println();
}

}

四.复杂度和应用:

时间复杂度:O(nlog2n)  空间复杂度:O(1)。  是不稳定的算法。

应用:也适用于海量的数据。

五.参考资料:

1.百度百科-堆排序:http://baike.baidu.com/view/157305.htm?fr=wordsearch

2.追竹的博客:http://blog.csdn.net/apei830/article/details/6584645

3.海子的博客园:http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html

六:相关排序代码下载:

包含(冒泡排序,桶排序,堆排序,插入排序,归并排序,快速排序,基数排序,选择排序,希尔排序)

免积分下载地址:http://download.csdn.net/detail/u014077165/7185895
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息