堆排序的思想是:首先将一个数列构造成一个大根堆,所谓大根堆就是一棵完全二叉树,数的父节点都要比子节点大。将一个数列生成一个大根堆之后,我们就可以确定这个数列的最大数位于根顶,然后,我们每次都将根顶的最大元素与根底的元素交换位置,这样一来,此时就不是大根堆了,所以接着我们要调整堆的元素排列顺序,使其重新变成大根堆,再继续将根顶元素与根底元素交换位置,再调整成大根堆,直到堆中元素全部调整完毕为止。
package alrithmetic;
import java.util.Arrays;
public class HeapSort {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 设置参数
int maxsize=50;
int maxvalue=100;
int maxtime=10000;
boolean success=true;
// 开始测试
for (int i = 0; i < maxtime; i++) {
int[] arr1=generarray(maxsize, maxvalue);
int[] arr2=copyarr(arr1);
// 开始测试两个排序函数
compare(arr2);
heapsort(arr1);
// 比较测试结果,只要有一次不一样,就退出测试
if (!isequal(arr1, arr2)) {
success=false;
return;
}
}
// 判断success的值为true or false
System.out.println(success?"well done":"fucking fucked");
// 最后使用我们自定义的堆排序函数
int[] arr3=generarray(maxsize, maxvalue);
printarray(arr3);
heapsort(arr3);
printarray(arr3);
}
// 堆排序函数入口
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 size=arr.length;
swap(arr, 0, --size);
while (size>0) {
sort(arr, 0, size);
swap(arr, 0, --size);
}
}
// 堆构造函数
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 sort(int[] arr,int index,int size){
int left=index*2+1;
int right=index*2+2;
while (left<size) {
int large=((arr[right]>arr[left])&&(right<size))?right:left;
large=arr[large]>arr[index]?large:index;
if (large==index) {
break;
}
swap(arr, index, large);
index=large;
left=index*2+1;
right=index*2+2;
}
}
// 交换函数
public static void swap(int[] arr,int i,int j){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
// 数组打印函数
public static void printarray(int[] arr){
if (arr==null) {
return;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
}
// 随机产生一个数组
public static int[] generarray(int maxsize,int maxvalue){
int[] arr=new int[(int) ((maxsize+1)*Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i]=(int)((maxvalue+1)*Math.random())-(int)(maxvalue*Math.random());
}
return arr;
}
// 复制数组,保证两个测试的数组内容大小一样
public static int[] copyarr(int[] arr){
int[] arr1=new int[arr.length];
for (int i = 0; i < arr.length; i++) {
arr1[i]=arr[i];
}
return arr1;
}
// 调用java自带的系统排序算法,用来做比较
public static void compare(int[] arr){
Arrays.sort(arr);
}
// 数组比较函数
public static boolean isequal(int[] arr1,int[] arr2){
if (arr1==null&&arr2!=null || arr1!=null&&arr2==null) {
return false;
}else if (arr1.length!=arr2.length) {
return false;
}else if (arr1==null&&arr2==null) {
return false;
}
for (int i = 0; i < arr2.length; i++) {
if (arr1[i]!=arr2[i]) {
return false;
}
}
return true;
}
}