堆排序(Java)

堆排序(Java)

上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import java.text.SimpleDateFormat;
import java.util.Date;

public class HeapSort {
public static void main(String[] args) {
//升序排列
//int[] arr = {4,6,8,5,9};
//创建80000个随机数
int[] arr = new int[8000000];
for (int i = 0; i <8000000; i++) {
arr[i] = (int) (Math.random()*8000000);//生成一个[0,8000000)的数
}
//System.out.println("排序前:");
//System.out.println(Arrays.toString(arr));
Date date1 = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
String date1Str = simpleDateFormat.format(date1);
System.out.println("排序前的时间是:"+date1Str);

long startMili=System.currentTimeMillis();// 当前时间对应的毫秒数
heapSort(arr);
long endMili=System.currentTimeMillis();

//System.out.println("排序后:");
//System.out.println(Arrays.toString(arr));


Date date2 = new Date();
String date2Str = simpleDateFormat.format(date2);
System.out.println("排序后的时间是:"+date2Str);

double h = (endMili-startMili)/1000.0;
System.out.println("总耗时为:"+(endMili-startMili)+"毫秒"+"="+ h + "秒");
}

public static void heapSort(int[] arr){
int temp = 0;
System.out.println("堆排序!");

分步完成
adjustHeap(arr, 1, arr.length);
System.out.println("NO.1:"+ Arrays.toString(arr));

adjustHeap(arr, 0 , arr.length);
System.out.println("NO.2:" + Arrays.toString(arr));

//一次完成
for (int i = arr.length / 2 - 1; i >= 0 ; i--) {
adjustHeap(arr, i, arr.length);
}

for (int j = arr.length - 1; j > 0 ; j--) {
//交换
temp = arr[j];
arr[j] = arr[0];
arr[0] = temp;
adjustHeap(arr, 0, j);
}

//System.out.println("数组=" + Arrays.toString(arr));
}

/**
* 功能:完成将以i对应的非叶子节点的树调整为大顶堆
* 举例:{4,6,8,5,9} => i=1 =>adjustHeap => {4,9,8,5,6}
* @param arr 待调整数组
* @param i 非叶子节点在数组中的索引
* @param length 对多少个元素继续调整,length在减少
*/
public static void adjustHeap(int[] arr,int i,int length){
int temp = arr[i]; //取出当前元素,保存在临时变量
//开始调整
for (int k = i*2+1; k <length ; k=k*2+1) {
if(k+1 < length && arr[k] <a rr[k+1] ){ //左子节点小于右子节点
k++; //k指向右子节点
}
if(arr[k] > temp){ //如果子节点大于结点
arr[i] = arr[k]; //把较大的值赋值给当前结点
i = k;
} else{
break;
}
} //当for循环结束,我们已经将以i为父结点的树的最大值放在最顶
arr[i] = temp;//将temp放到最后调整的位置
}
}
Donate comment here