堆排序
Posted Xin.Wang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了堆排序相关的知识,希望对你有一定的参考价值。
堆排序过程:
主函数中:
public void main(String[] args)
1. 定义初始化数组:int[] a = new int[]{.............}
2. 循环建堆 调用建堆函数:
for (int i = 0; i < a.length - 1; i++) {
buildMaxHeap(a, a.length - 1 - i); //建堆函数
swap(a, 0, a.length - i - 1); // 置换数据函数
}
3. 输出排序好的数组:System.out.println(Arrays.toString(a));
建堆函数中:
public static void buildMaxHeap(int[]data, int lastIndex){}//data: 数组 lastIndex 最后的节点
1. 从最后的一个节点的父节点开始进行循环:for(int i = (lastIndex - 1)/2; i >= 0; i--){
2. k保存正在判断的节点: int k = i:
3. 判断当前k节点的子节点存在,若存在进入循环:while(2 * k + 1 <= lastIndex>)
4. 当k节点的子节点存在时,biggerIndex储存k节点左节点索引 int biggerIndex = 2 * k + 1
5. 判断k节点的右节点是否存在, if(biggerIndex < lastIndex){
6. 若存在则比较k节点的左右节点的大小 if(data[biggerIndex]<data[biggerIndex +1]);
7. 若右节点的值比左节点的值大,则将biggerIndex的值+1(指向右节点) : biggerIndex++
8. 将k节点的值和biggerIndex节点的值进行比较,若 k 节点的值比biggerIndex节点的值小,则交换k节点和biggerIndex节点的值,反之,break:
if (data[k] < data[biggerIndex]) {
// 交换他们
swap(data, k, biggerIndex);
// 将biggerIndex赋予k,开始while循环的下一次循环,重新保证k节点的值大于其左右子节点的值
k = biggerIndex;
} else {
break;
}
交换函数中:
public static void swap(int[] a , int i ,int j){}对值进行交换:
int temp = a[i];
a[i] = a[j];
a[j] = temp;
1 import java.util.Arrays; 2 3 public class HeapSort { 4 public static void main(String[] args) { 5 int a[] = { 1, 23, 5, 4, 8, 6, 3, 2, 1, 5, 8, 4, 4, 5, 2, 1 }; 6 // 循环建堆 7 for (int i = 0; i < a.length - 1; i++) { 8 buildMaxHeap(a, a.length - 1 - i); // 建堆函数 9 swap(a, 0, a.length - i - 1); // 交换函数 10 } 11 System.out.println(Arrays.toString(a)); 12 } 13 14 private static void buildMaxHeap(int[] data, int lastIndex) { 15 // TODO Auto-generated method stub 16 for (int i = (lastIndex - 1) / 2; i >= 0; i--) { // 从最后一个节点的父节点开始 17 int k = i; 18 // 2k+1 <= lastIndex 判断是否存在子节点 19 while (k * 2 + 1 <= lastIndex) { 20 int biggerIndex = 2 * k + 1;// 用biggerIndex保存k节点的左孩子的节点 21 if (biggerIndex < lastIndex) {// 判断k节点的右孩子(节点)是否存在 22 if (data[biggerIndex] < data[biggerIndex + 1]) {// 若右孩子存在,判断左右孩子的值得大小 23 biggerIndex++;// 若右孩子比左孩子大,biggerIndex记录右孩子的节点值biggerIndex++ 24 } 25 } 26 // 判断K节点的值是否小于其较大子节点(孩子)的值 27 if (data[k] < data[biggerIndex]) { 28 swap(data, k, biggerIndex);// 若k节点的值小于其较大子孩子的值,交换k节点和biggerIndex节点的值 29 k = biggerIndex;// 将biggerIndex(较大子节点的索引)赋给 k 30 } else { 31 // 若k节点的值不小于其较大子节点的值则break;(跳出循环) 32 break; 33 } 34 } 35 } 36 } 37 38 private static void swap(int[] data, int i, int j) { 39 // TODO Auto-generated method stub 40 int temp = data[i]; 41 data[i] = data[j]; 42 data[j] = temp; 43 } 44 }
以上是关于堆排序的主要内容,如果未能解决你的问题,请参考以下文章