2019-02-13 13:26:34 436浏览
今天扣丁学堂Java培训老师给大家介绍一下关于Java排序算法之堆排思想及代码实现,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧。如图:
最后得到的大顶堆:
// 插入数使其形成大顶堆
public static void heapInsert(int[] arr, int index) {
while(arr[index] > arr[(index - 1)/2]) {
swap(arr, index, (index - 1)/2);
index = (index - 1)/2;
}
}
在该例子中应该是将2和6进行交换,得到:
这时候的数组最后一个值就是最大的了,也就是最后一个位置上的数已经排好了,接下来我们就要将除了最后位置的结点之外剩下的完全二叉树进行排序了,即:
该例子中:index位置上的值是2,该位置的孩子结点分别为3和5,将2和5进行交换之后,index=index*2+2=2,此时index位置结点是一个叶子结点,不再进行交换,此时构成了一个新的大顶堆。如图:
/**
* @author LZD 2018/03/01
*/
public class HeapSort {
public static void heapSort(int[] arr) {
if(arr == null || arr.length < 2)
return;
// 构建大顶堆
for(int i = 0;i < arr.length;i++) {
heapInsert(arr, i);
}
int heapSize = arr.length;
swap(arr, 0, --heapSize);
while(heapSize > 0) {
heapify(arr, 0, heapSize);
swap(arr, 0, --heapSize);
}
}
// 插入数使其形成大顶堆
public static void heapInsert(int[] arr, int index) {
while(arr[index] > arr[(index - 1)/2]) {
swap(arr, index, (index - 1)/2);
index = (index - 1)/2;
}
}
// 将堆化为大顶堆
public static void heapify(int[] arr, int index, int heapSize) {
// 先判断当前的index位置的结点是否是叶子结点
int left = index * 2 + 1;
while(left < heapSize) {
// 不是叶子结点则选出index位置结点的孩子结点中较大的赋给largest
int largest = left+1 < heapSize && arr[left + 1] > arr[left]
? left + 1: left;
largest = arr[largest] > arr[index] ? largest : index;
if(largest == index) {
break;
}
swap(arr, largest, index);
index = largest;
left = index * 2 + 1;
}
}
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
// for test 打印数组
public static void printArray(int[] arr) {
for(int i = 0;i < arr.length;i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
// for test
public static void main(String[] args) {
int[] arr = {2, 1, 3, 6, 0, 5};
heapSort(arr);
printArray(arr);
}
}
【关注微信公众号获取更多学习资料】