package com.yu.datastructure.sort;
import java.util.Arrays;
/**
* 堆排序
* 将待排序序列构造成一个大顶堆
*此时,整个序列的最大值就是堆顶的根节点。
*将其与末尾元素进行交换,此时末尾就为最大值。
*然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。
* @author Administrator
*
*/
public class HeadSortDemo3 {
public static void main(String[] args) {
int[] arr = {100,3,5,34,563,32,1234,57,53,2,5,78};
headSort(arr);
System.out.println("排序之后的数据:" + Arrays.toString(arr));
}
/**
* 开始排序
* @param arr
*/
private static void headSort(int[] arr) {
//先把数据转换为大顶推
for (int i = arr.length/2-1; i >= 0; i--) {
adjustHead1(arr,i,arr.length);
}
//开始把头结点的元素放在尾节点
for (int i = arr.length-1; i > 0; i--) {
int temp = arr[i];
arr[i] = arr[0];
arr[0] = temp;
adjustHead1(arr,0,i);
}
}
/**
* 转换为大顶推
* @param arr 数组
* @param i 父节点的下标
* @param length 数组的长度
*/
private static void adjustHead(int[] arr, int i, int length) {
int temp = arr[i];//记录父节点的值
//找到父节点的左节点
for (int j = i*2 + 1; j < length; j=i*2 + 1) {
//判断左节点和右节点值的大小
if(j+1 < length && arr[j] < arr[j+1]){
j++;
}
if(temp < arr[j]){
arr[i] = arr[j];
i=j;
}else{
break;
}
}
arr[i] = temp;
}
/**
* 转换为小顶堆
* @param arr 数组的长度
* @param i 父节点的下标
* @param length 数组的长度
*/
public static void adjustHead1(int[] arr, int i, int length){
int temp = arr[i];
//取出父节点的左子节点
for (int j = i*2 + 1; j < length; j=i*2 + 1) {
if(j+1 < length && arr[j] > arr[j+1]){
j++;
}
//开始比较 父节点比叶子节点大
if(arr[i] > arr[j]){
arr[i] = arr[j];
i = j;
}else{
break;
}
}
arr[i] = temp;
}
}