堆排序
- 是一种选择排序。 平均时间复杂度为0(nlogn),是不稳定排序
- 大顶堆: 完全二叉树,每个节点的值都大于或等于其左右子节点的值。(左右子节点的值不作要求)
- 小顶堆:完全二叉树,每个节点的值都小于或等于其左右子节点的值
大顶堆:
小顶堆:
堆排序的基本思想
- 将待排序序列构造层一个大顶堆 (左节点2n+1; 右节点2n+2; 父节点(i-1)/2)
- 序列的最大值处于,顶部的根节点
- 先将数组变成大顶堆形式
- 将大顶堆堆顶与最小叶子节点交换,使大顶堆位于最小叶子节点除,将其移除(后面不考虑)
- 在对其剩余顶堆进行处理,使其重新变成大顶堆
- 循环4-5,直至所有元素被移除
升序
class HeapSort {
public static void heapSort(int[] arr){
bigHeap(arr);
int size = arr.length;
while (size > 1){
swap(arr,0,size-1);
size--;
heapRestRec(arr,0,size);
}
}
public static void bigHeap(int[] arr){
for (int i = 0; i < arr.length; i++) {
int currentIndex = i;
int fatherIndex = (i-1)/2;
while (arr[fatherIndex]<arr[currentIndex]){
swap(arr,fatherIndex,currentIndex);
currentIndex = fatherIndex;
fatherIndex = (currentIndex-1)/2;
}
}
}
public static void heapRest(int[] arr, int index, int size){
int left = index*2 +1;
int right = index*2 +2;
int bigIndex;
while (left < size){
if (right <size && arr[right] > arr[left] ){
bigIndex = right;
}else {
bigIndex = left;
}
if (arr[bigIndex] > arr[index]){
swap(arr,bigIndex,index);
index = bigIndex;
left = index*2 +1;
right = index*2 +2;
}else {
break;
}
}
}
public static void heapRestRec(int[] arr, int index, int size){
int left = index*2 +1;
int right = index*2 +2;
int bigIndex;
if (left >= size){
return;
}
if (right<size && arr[right]> arr[left]){
bigIndex = right;
}else {
bigIndex = left;
}
if (arr[bigIndex] > arr[index]){
swap(arr,bigIndex,index);
heapRestRec(arr,bigIndex,size);
}
}
public static void swap(int[] arr, int ind1, int ind2){
int temp = arr[ind1];
arr[ind1] = arr[ind2];
arr[ind2] = temp;
}
public static void main(String[] args) {
int [] arr = {1,2,34,5,6,8};
heapSort(arr);
for (int e: arr
) {
System.out.println(e);
}
}
}
降序:
public static void heapSortDescent(int[] arr){
smallHeap(arr);
int size = arr.length;
while (size > 1){
swap(arr,0,size-1);
size--;
smallHeapRes(arr,0,size);
}
}
public static void smallHeap(int[] arr){
for (int i = 0; i < arr.length; i++) {
int cur = i;
int father = (i-1)/2;
while (arr[cur] < arr[father]){
swap(arr,cur,father);
cur = father;
}
}
}
private static void smallHeapRes(int[] arr, int index, int size) {
int left = index*2+1;
int right = index*2 +2;
int smallInd;
if (left >= size){
return;
}
if (right < size && arr[right]<arr[left]){
smallInd = right;
}else {
smallInd = left;
}
if (arr[index] > arr[smallInd]){
swap(arr,index,smallInd);
smallHeapRes(arr,smallInd,size);
}
}
public static void main(String[] args) {
int [] arr = {1,2,34,5,6,8};
heapSortDescent(arr);
for (int e: arr
) {
System.out.println(e);
}
}
}