堆排序Java实现

堆概念:

是一种完全二叉树结构,分为大根堆和小根堆,每一个非叶子节点都大于(大根堆是大于,小根堆事小于)它的两个子节点。

堆排序:步骤分为三步:

1 :初始化大根堆(小根堆也可以,本篇以大根堆为例)

2:交换堆顶最大值和数组最后一位,

3:交换位置后的堆进行大根堆调整

4:循环进行2步骤,交换堆顶和数组倒数第二位,第三位等等直到第一位。。。

时间复杂度分析:

初始化堆排序结构时间复杂度需要 N * logN

每一次交换后维护新的大根堆复杂度是logN,进行N次遍历交换,所以总的时间复杂度:N * logN

代码如下

 1 package com.secbro.test;
 2 
 3 import java.util.Arrays;
 4 
 5 public class HeapSort {
 6 
 7     //test
 8     public static void main(String[] args) {
 9         int[] num = {10, 23, 17, 88, 39, 13, 11, 109, 108, 383, 100, 1, 10, 14};
10         initBuildHeap(num, 0, num.length - 1);
11         System.out.println("初始化大根堆:" + Arrays.toString(num));
12         for (int i = num.length - 1; i >= 0; i--) {
13             swap(num, 0, i);
14             rebuildHeap(num, 0, i);
15         }
16         System.out.println("堆排序结果:" + Arrays.toString(num));
17     }
18 
19     //构建初始化大根堆 此步骤时间复杂度是:N(logN)
20     private static void initBuildHeap(int[] num, int index, int end) {
21 
22         if (num == null || index > end) {
23             return;
24         }
25         for (int i = end; i >= index; i--) {
26             int parent = (i - 1) / 2;
27             if (num[i] > num[parent]) {
28                 swap(num, i, parent);
29                 initBuildHeap(num, index, i);
30             }
31         }
32     }
33 
34     //维护新的大根堆结构
35     private static void rebuildHeap(int[] num, int index, int end) {
36         if (num == null || index > end) {
37             return;
38         }
39         int left = 2 * index + 1;
40         int right = 2 * index + 2;
41         if (left < end && num[index] < num[left]) {
42             swap(num, index, left);
43             rebuildHeap(num, left, end);
44         }
45         if (right < end && num[index] < num[right]) {
46             swap(num, index, right);
47             rebuildHeap(num, right, end);
48         }
49     }
50 
51     //交互数组中 num[left] 和 num[right] 位置
52     private static void swap(int[] num, int left, int right) {
53         int temp = num[left];
54         num[left] = num[right];
55         num[right] = temp;
56     }
57 }

打印结果

初始化大根堆:[383, 109, 14, 108, 100, 13, 10, 17, 88, 23, 39, 1, 10, 11]
堆排序结果:[1, 10, 10, 11, 13, 14, 17, 23, 39, 88, 100, 108, 109, 383]

猜你喜欢

转载自www.cnblogs.com/wanghongsen/p/9235690.html