package com.sonihr.NowCoderExam;/*
@author 黄大宁Rhinos
@date 2019/4/24 - 15:07
**/
import sun.security.util.Length;
import java.util.Arrays;
public class HeapSortSolution {
private void swap(int[] a,int i,int j){
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
/**
* 建树过程,从最后一个非叶子节点到根节点,如果左右儿子中的较大值比自己大则交换
* 依次类推,要和所有的子孙节点比较完毕
* 建立出的堆保证根节点一定大于子节点,但不保证有序
* */
public void buildMaxHeap(int[] a){
int len = a.length;
int tail = (len-1-1)/2;
for(int i=tail;i>=0;i--){
int parent = i;
while(parent<len){
int left = parent*2+1;
int right = parent*2+2;
int max = 0;
if(left>=len&&right>=len)
break;
else if(left>=len)
max = right;
else if(right>=len)
max =left;
else
max = a[left]>a[right]?left:right;
if(a[max]>a[parent])
swap(a,max,parent);
parent = max;
}
}
}
/**
* 从最后向前插入,如果父节点比自己小则替换
* 注意,这里只影响父节点和自己,不影响其他节点
* */
public int[] insertMaxHeap(int[] a,int val){
int[] b = Arrays.copyOf(a,a.length+1);
b[a.length] = val;
int i = a.length;
while(i>=0){
int parent = (i-1)/2;
if(b[i]>b[parent]){
swap(b,i,parent);
i = parent;
}else
break;
}
return b;
}
/**
* 删除节点,比如删除index节点,则将尾节点放置到index位置上
* 然后寻找到index应该在的位置
* 类似于建树的过程
* */
public int[] deleteMaxHeap(int[] a,int index){
int tail = a.length-1;
swap(a,index,tail);
int[] b = Arrays.copyOf(a,a.length-1);
int parent = index;
while(parent<tail){
int left = parent*2+1;
int right = parent*2+2;
int max = 0;
if(left>=tail&&right>=tail)
break;
else if(left>=tail)
max = right;
else if(right>=tail)
max =left;
else
max = b[left]>b[right]?left:right;
if(b[max]>b[parent])
swap(b,max,parent);
else break;
parent = max;
}
return b;
}
public int[] heapSort(int[] a){
int[] b = new int[a.length];
int len = a.length;
for(int i=0;i<len;i++){
b[i] = a[0];
a = deleteMaxHeap(a,0);
}
return b;
}
public static void main(String[] args) {
int[] a = {1, 3, 4, 5, 7, 2, 6, 8, 0};
HeapSortSolution sortSolution = new HeapSortSolution();
sortSolution.buildMaxHeap(a);
out(a);
a = sortSolution.insertMaxHeap(a,11);
out(a);
a = sortSolution.deleteMaxHeap(a,0);
out(a);
int[] b = sortSolution.heapSort(a);
out(b);
}
public static void out(int[] a){
for(int i:a){
System.out.print(i+" ");
}
System.out.println();
}
}
堆排序的Java实现
最新推荐文章于 2024-06-03 19:56:43 发布