`
ordinary
  • 浏览: 77220 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

计算机程序设计艺术-----堆排序

阅读更多
堆排序:一种基于堆的排序算法;
一些基础概念
堆定义:
当且仅当该序列满足如下性质(简称为堆性质):
(1) ki≤K2i且ki≤K2i+1 或(2)Ki≥K2i且ki≥K2i+1(1≤i≤ n) //ki相当于二叉树的非叶结点,K2i则是左孩子,k2i+1是右孩子
若将此序列所存储的向量R[1..n]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:
树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。
下图为数组对应的大根堆和小根堆。

堆的高度:
堆可以被看成是一棵树,结点在堆中的高度可以被定义为从本结点到叶子结点的最长简单下降路径上边的数目;定义堆的高度为树根的高度。我们将看到,堆结构上的一些基本操作的运行时间至多是与树的高度成正比,为O(lgn)
大根堆的堆排序思想:
1) 初始化R[1…n]为大根堆,该堆为无序的;
2) 交换R[1]和R[n],R[1…n-1]为无序的,R[n]为有序的;
3) 初始化R[1…n-1]为大根堆;
4) 交换R[1]和R[n-1],R[1…n-2]为无序的,R[n-1…n]为有序的;
依次重复,知道排好序为止。
算法如下:
/**
* 建立堆
* heap为需要建堆的数组,
* root建堆的起始根
* index为未排序的最后叶子节点
*/
private static void createHeap(int[] heap, int root, int index) {
int left;
int right;
int tmp;
if(root>=index){
return ;
}
while (root >= 0) {
left = root << 1;
right = (root << 1) + 1;
if (right <= index) {
if (heap[root] < heap[right]) {
tmp=heap[root];
heap[root]= heap[right];
heap[right]=tmp;
createHeap(heap, right, index);
}
}
if (left <= index) {
if (heap[root] < heap[left]) {
tmp=heap[root];
heap[root]= heap[left];
heap[left]=tmp;
createHeap(heap, left, index);
}
}
root--;
}
}

public static void heapSort(int[]heap, int index) {
int i, j, Temp;
// 将二叉树转成Heap
for (i = (index / 2); i >= 1; i--)
createHeap(heap,i, index);
// 开始进行堆排序
for (i = index ; i >= 1; i--) {
Temp = heap[i]; // Heap的Root值和最后一个值交换
heap[i] = heap[0];
heap[0] = Temp;
createHeap(heap,0, i-1); // 对其余数值重建堆
System.out.print("排序中: ");
for (j = 0; j <= index; j++)
System.out.printf("%3s", heap[j]);
System.out.println("");
}
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics