堆排序

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 }

 

以上是关于堆排序的主要内容,如果未能解决你的问题,请参考以下文章

选择排序(简单选择排序堆排序的算法思想及代码实现)

排序--08---堆排序

python代码实现堆排序

算法-java代码实现堆排序

一文带你了解堆排序

堆排序