堆排序

来源:互联网 发布:数据结构设计怎么写 编辑:程序博客网 时间:2024/06/05 13:33
堆排序是先将待排序的数看成完全二叉树的结构排列.以大顶堆为例,堆顶数总是大于左右孩子.

堆排序的思想:
1.现将所有数初始化成一个大顶堆
2.将堆顶a[0]和最后一个子节点a[len-1]交换位置
3.将余下的数再重新构建成大顶堆
4.重复2,3过程,直到全部排序完成

(截图于百度百科)

构建一个简单的大顶堆的思路就是从第一个非叶子节点开始(至少有一个孩子,因为叶子节点从逻辑上来说就是个大顶堆)进行往回构建.(堆构建)
.将堆顶与左右孩子中最大的数比较,若堆顶小则交换.这样局部的大顶堆就形成了.但是孩子节点处就可能变成非大顶堆了,于是在对孩子进行构建大顶堆.
其实就是说在对一个节点构建大顶堆的时候,要一直构建到他的所有孩子节点都满足大顶堆的时候才算结束.(堆调整)
堆构建完毕后,那么最大的数就已经在堆顶了,将他于最后一个数交换,然后在对最后一个数之前得所有数进行堆构建,直到出现新的堆顶,重复过程.(堆排序),堆排序这里其实只要构建后把堆顶不断输出就行了,怎么存储这些堆顶数是无所谓的.

// 堆调整就是对一个节点所在的子树进行大顶堆构建
private static void maxHeapify(int a[], int start, int end) {
int parent = start;
int child = parent * 2 + 1;// 左孩子
int temp;
while (child <= end) {
if (child + 1 <= end && a[child] < a[child + 1])
child++;// 右孩子比较大
if (a[child] < a[parent])// 父节点大 无需交换
break;
// 孩子节点大 进行交换
temp = a[child];
a[child] = a[parent];
a[parent] = temp;
// 孩子节点进入堆调整
parent = child;
child = parent * 2 + 1;
}
}

public static void heapSort(int a[]) {
int len = a.length;
int temp;
// len/2-1为第一个非叶子节点
for (int i = len / 2 - 1; i >= 0; i--)
maxHeapify(a, i, len - 1);// 构建初始化大顶堆
for (int i = len - 1; i >= 0; i--) {
// 将堆顶放在数组最后
temp = a[0];
a[0] = a[i];
a[i] = temp;
// 将剩下的数在重新构建大顶堆
maxHeapify(a, 0, i - 1);
}
}
堆排序的代码重要的是理解堆排序的思想,不断的堆调整后取出堆顶数.


0 0
原创粉丝点击