public class 堆排序的实现// 是选择排序的进一步实现
{
/*
* 选择排序的思想:每一趟在n-i+1(i=1,2,...,n-1)个记录中选取关键字最小的记录作为有序序列中第i个记录
* 排序只需要的一个记录大小的辅助空间 其时间复杂度为nlogn
* 若在输出栈顶的最小值之后,是的剩余n-1个元素的序列重又构建一个堆,则得到n个元素的最小值.如此反复执行,便能得到一个有序序列,
* 至二个过程称之为堆排序
*/
/*
* 建大顶堆过程: 1:从最后一个结点开始进行(如果其有兄弟结点,则两者进行比较 选择其中的最大值
* 与其父结点进行比较,如果大于父结点则进行互换,直至到root结点) 2:直到最后一个叶子结点进行调整完毕后 及建堆完成
*/
private static void buildMaxHeap(int a[], int end)
{
// 开始i的索引是最后一个非叶子结点(从root结点进行层次遍历形成的序列的最后一个非叶子结点)
for (int i = (end - 1) / 2; i >= 0; i--)
{
// k表示当前正在进行判断的结点索引
int cur = i;
// 当前cur的子结点是否存在
while (cur * 2 + 1 <= end)
{
// cur的左孩子结点 假设为biggerIndex
int biggerIndex = cur * 2 + 1;
// cur的右孩子存在
if (cur * 2 + 1 < end)
{
int rightOfCur = cur * 2 + 2;
// 左孩子的值小于右孩子的值
if (a[biggerIndex] < a[rightOfCur])
{
biggerIndex++;
}
}
// 如果cur的值小于它的较大子结点值 进行交换
if (a[cur] < a[biggerIndex])
{
int temp = a[cur];
a[cur] = a[biggerIndex];
a[biggerIndex] = temp;
// 为了保证索引为biggerIndex的结点的子结点都小于biggerIndex
cur = biggerIndex;
}
else
{
break;
}
}
}
}
public static void main(String[] args)
{
int a[] =
{ 13, 38, 27, 65, 76, 28, 96 };
//每一次只能找出一个
for (int i = 0; i < a.length - 1; i++)
{
buildMaxHeap(a, a.length - 1 - i);
// 交换堆顶和堆尾
int temp = a[0];
a[0] = a[a.length - 1 - i];
a[a.length - 1 - i] = temp;
System.out.println(Arrays.toString(a));
}
}
}
转载于:https://www.cnblogs.com/qingtianBKY/p/7126521.html