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

Java实现-高效排序算法之堆排序

2016-05-12 22:29 519 查看
堆排序只需要一个记录大小的辅助空间,每个待排序的记录仅占有一个存储空间。

在处理堆排序时面临两个问题:一个是如何建堆。另一个是如何在输出堆顶后进行调整,成为一个新堆。

建堆的过程主要是通过在n/2(取下限)处开始,反复进行“筛选”的过程。具体过程见算法分析及注释。

//堆排序的伪代码

//heapsort(data[])

// data转变成一个堆;

// for i = data.length-1 downto 2

// 将根和i位置上的元素交换;

// 恢复树data[0],...,data[i-1]的堆属性;

public class Heapsort {

public void heapsort(Object[] data){

//将数组转换成一个堆

for(int i = data.length/2-1; i >= 0; --i)

moveDown(data, i, data.length-1);

//实现位置的调整

for(int i = data.length-1; i >= 1; --i){

swap(data, 0, i);

moveDown(data, 0, i-1);

}

}

//将一个数组创建成一个堆(根元素沿着树向下移动的算法实现)

void moveDown(Object[] data, int first, int last){

int largest = 2*first +1;

while(largest <= last){

//first节点有两个孩子节点(2*first+1和2*first+2),

//因此Comparable比较的是两个孩子节点的元素大小

if(largest < last &&

((Comparable)data[largest]).compareTo(data[largest+1]) < 0)

largest++;

//比较根节点和最大节点处值的大小,如果满足条件,则交换值的大小,并且移动元素

if(((Comparable)data[first]).compareTo(data[largest]) < 0){

swap(data, first, last);

first = largest;

largest = 2*first +1;

}

else

//不满足堆的循环时,退出循环

largest = last + 1;

}

}

//实现数组中两个元素的交换

void swap(Object[] a, int e1, int e2){

Object tmp = a[e1];

a[e1] = a[e2];

a[e2] = tmp;

}

}

堆排序在建堆的过程中heapsort()使用moveDown(),共执行O(n)步。第二步在调整的过程中是对logi在1到(n-1)上的和,即O(nlogn)。

在最好的情况下,堆排序比较的总次数为O(n)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: