调整堆的代码
堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:
大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;
小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;
堆排序的平均时间复杂度为 Ο(nlogn)。
下面是堆重建的代码
/**
* 对小堆进行选择重建
* arr 是数组
* n 是元素个数
* i 是你期望从哪里开始把当前这个堆进行重建
*/
public static void heapify(int arr[], int n, int i) {
int max = i;
int c1 = 2 * i + 1;
int c2 = 2 * i + 2;
if (i > n) {
return;
}
if (c1 < n && arr[c1] > arr[max]) {
max = c1;
}
if (c2 < n && arr[c2] > arr[max]) {
max = c2;
}
if (max != i) {
swap(arr, max, i);
heapify(arr, n, max);
}
}
测试
package cn.axzo.apollo.server.util.sortUtil;
import cn.hutool.core.util.StrUtil;
/**
* 堆排序
*
* @author zhuguanghong
*/
public class HeapSort {
public static void main(String[] args) {
int array[] = {4, 10, 3, 5, 1, 2};
heapify(array, 6, 0);
printArr(array);
}
/**
* 对小堆进行选择重建
*/
public static void heapify(int arr[], int n, int i) {
int max = i;
//左儿子的索引
int c1 = 2 * i + 1;
//右儿子的索引 问怎么推到来的? 要不你先背着?
int c2 = 2 * i + 2;
//快速返回 跳出递归
if (i > n) {
return;
}
if (c1 < n && arr[c1] > arr[max]) {
max = c1;
}
if (c2 < n && arr[c2] > arr[max]) {
max = c2;
}
if (max != i) {
swap(arr, max, i);
heapify(arr, n, max);
}
}
public static void swap(int[] arr, int a, int b) {
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
public static void printArr(int[] arr) {
System.out.println(StrUtil.join("-", arr));
}
}
输出的结果: 10-5-3-4-1-2
完整的构建堆
/**
* 从最后一个节点的父亲节点开始重建
* @param arr 数组
* @param n 数组长度
*/
public static void buildHeap(int[] arr,int n){
//得出最后一个节点的索引
int last_node_parent = n - 1;
//按照公式 得出他的父亲的索引
int parent = (last_node_parent-1)/2;
//因为节点的顺序从上到下从左到右是顺序的 所以可以从最小的堆开始重建
for(int i =parent;i>=0;i--){
heapify(arr,n,i);
}
//重建完以后堆是可以的
}
测试结果: 10-5-3-4-1-2
对一个处理过的堆 进行排序操作
package cn.axzo.apollo.server.util.sortUtil;
import cn.hutool.core.util.StrUtil;
/**
* 堆排序
*
* @author zhuguanghong
*/
public class HeapSort {
public static void main(String[] args) {
int array[] = {4, 10, 3, 5, 1, 2};
// heapify(array, 6, 0);
// buildHeap(array,6);
headSort(array);
printArr(array);
}
/**
* 对小堆进行选择重建
*/
public static void heapify(int arr[], int n, int i) {
int max = i;
int c1 = 2 * i + 1;
int c2 = 2 * i + 2;
if (i > n) {
return;
}
if (c1 < n && arr[c1] > arr[max]) {
max = c1;
}
if (c2 < n && arr[c2] > arr[max]) {
max = c2;
}
if (max != i) {
swap(arr, max, i);
heapify(arr, n, max);
}
}
/**
* 从最后一个节点的父亲节点开始重建
* @param arr 数组
* @param n 数组长度
*/
public static void buildHeap(int[] arr,int n){
//得出最后一个节点的索引
int last_node_parent = n - 1;
//按照公式 得出他的父亲的索引
int parent = (last_node_parent-1)/2;
//因为节点的顺序从上到下从左到右是顺序的 所以可以从最小的堆开始重建
for(int i =parent;i>=0;i--){
heapify(arr,n,i);
}
//重建完以后堆是可以的
}
public static void headSort(int[] arr){
int n =arr.length;
buildHeap(arr, arr.length);
for(int i = n-1 ;i>=0 ;i--){
swap(arr,0,i);
heapify(arr,i,0);
}
}
public static void swap(int[] arr, int a, int b) {
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
public static void printArr(int[] arr) {
System.out.println(StrUtil.join("-", arr));
}
}