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

java实现的堆排序(java)

2014-05-04 14:20 330 查看
//堆排序
public class HeapSorter {

// 主线程main方法
public static void main(String[] args) {

Integer[] testArr = new Integer[] { 7, 9, 1, 6 };
heapSort(testArr, new Comparator<Integer>() {

@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
printArr(testArr);
}

// 对数组进行堆排序
public static final <T> void heapSort(T[] testArr, Comparator<T> comparator) {

// 将数组初始化为最大堆
buildHeap(testArr, comparator);

// 循环排序,依此将最大的数归位.
for (int i = testArr.length - 1; i > 0; i--) {
// 交换最后一个元素与根元素(归位最大数)
swap(testArr, i, 0);

// 维护堆排序
heapify(testArr, 0, i + 1, comparator);
}
}

// 打印数组元素
public static final <T> void printArr(T[] testArr) {

for (T t : testArr) {
System.out.print(t.toString() + "; ");
}
System.out.println();
}

// 交换数组中的2个元素
public static final <T> void swap(T[] testArr, int i, int j) {

T tempEle = testArr[i];
testArr[i] = testArr[j];
testArr[j] = tempEle;
}

// 把数组转化为最大堆(最大堆的定义是用递归定义的,这里构造的时候,就采用递归思想)
public static final <T> void buildHeap(T[] testArr, Comparator<T> comparator) {
                // 从最后一个节点的父节点开始. 以它为根节点的树具有堆树性质, 然后一层一层的向上后退
for (int i = (testArr.length / 2) - 1; i >= 0; i--) {
heapify(testArr, i, comparator);
}
}

// 维护以startIndex为根元素的堆树, 前提是startIndex为根的左右子树具有堆的性质
public static final <T> void heapify(T[] testArr, int startIndex, int size, Comparator<T> comparator) {

// 取得最大值
int nextIndex = startIndex;
int leftIndex = left(startIndex);
int rightIndex = right(startIndex);
if (leftIndex < size - 1 && comparator.compare(testArr[leftIndex], testArr[startIndex]) > 0)
nextIndex = leftIndex;
if (rightIndex < size - 1 && comparator.compare(testArr[rightIndex], testArr[nextIndex]) > 0)
nextIndex = rightIndex;
if (nextIndex == startIndex)
return;

swap(testArr, startIndex, nextIndex);

// 维护最大堆
heapify(testArr, nextIndex, size, comparator);
}

// 维护以startIndex为根元素的堆树
public static final <T> void heapify(T[] testArr, int startIndex, Comparator<T> comparator) {

heapify(testArr, startIndex, testArr.length, comparator);
}

// 获得以startIndex为根元素的左节点, 返回的是数组索引
public static final int left(int startIndex) {

return ((startIndex + 1) << 1) - 1;// 注意这里位运算的优先级问题
}

// 获得以startIndex为根元素的右节点, 返回的是数组索引
public static final int right(int startIndex) {

return ((startIndex + 1) << 1);
}

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