您的位置:首页 > 其它

堆排序

2016-09-14 23:18 393 查看
package Sort;

import org.junit.Test;

public class HeapSort {

// 交换数组中的两个元素
public void exchange(int[] array, int index1, int index2) {
int tmp = array[index1];
array[index1] = array[index2];
array[index2] = tmp;
}

/**
* 功能 保证index索引后的元素都满足最大堆的性质
*
* @param array
*            一个无序的数组
* @param index
*            数组的一个下标
* @parem heapSize 真正有效的堆元素数量
*/
public void MaxHeapify(int[] array, int index, int heapSize) {

// 假设根节点为array[left],array[right]满足最大堆的性质
int left = 2 * index;
int right = left + 1;
int largest = index;
// largest用来指向最大元素的下标
if (left <= heapSize && array[left] > array[index])
largest = left;
if (right <= heapSize && array[right] > array[largest])
largest = right;
if (largest != index) {
exchange(array, largest, index);
MaxHeapify(array, largest, heapSize);
}
}

// 构建最大堆,注意下标从1开始,类似于完全二叉树
public void BuildMaxHeap(int[] array) {

// 不考虑array[0]
int i = (array.length - 1) / 2;
while (i >= 1) {
// 此时堆中有效的元素是数组的长度-1个
MaxHeapify(array, i, array.length - 1);
--i;
}
}

// 真正的堆排序算法要开始了
public void heapSort(int[] array) {
int heapSize = array.length - 1;
BuildMaxHeap(array);
for (int i = array.length - 1; i > 1; --i) {
exchange(array, 1, i);
MaxHeapify(array, 1, --heapSize);
}
}

// 返回数组中的最大元素,并从数组中删除它
// 返回优先队列中优先级最高的元素,出队
// 实际上出队的过程只是把元素拿到了数组的尾部
public int heapExtractMax(int[] array, int heapSize) {
// 注意优先队列中并不存储下标为0的元素
if(array.length == 1 || array == null)
return -1;
int max = array[1];
array[1] = array[heapSize];
MaxHeapify(array, 1, heapSize);
return max;
}

// 将数组下标为i的值更改为key,如果key值小于原来索引位置的值,则直接退出
public void heapIncreaseKey(int[] array, int i, int key) {
if (key < array[i])
return;
array[i] = key;
while (i > 1 && array[i / 2] < array[i]) {
exchange(array, i / 2, i);
i = i / 2;
}
}

@Test
public void test() {
int[] array = { -1, 4, 1, 3, 2, 16, 9, 10, 14, 8, 7 };
heapSort(array);
Array.print(array);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: