不稳定排序
比较次数与初始序列有关(基本有序时可以减少堆的调整次数)
// HeapSort.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
void swap(int *a,int *b);
void printArr(int arr[],int length){
for(int i=1;i<=length;i++)
printf("%d ",arr[i]);
printf("\n");
}
void adjustHeap(int arr[],int size,int i);
void buildHeap(int arr[],int size){
//首先要进行建堆,从堆的倒数第二层的最后一个开始,到顶层,对每个节点调整堆
for(int i=size/2;i>=1;i--)
adjustHeap(arr,size,i);
}
void adjustHeap(int arr[],int size,int i){
//调整第i个节点,比较左孩子、右孩子、自己,选出大的放到上面,并递归调整交换的节点
int left = 2*i;
int right = 2*i+1;
int larger = i;
if(left<=size&&arr[left]>arr[larger]){
larger = left;
}
if(right<=size&&arr[right]>arr[larger]){
larger = right;
}
if(i!=larger){
swap(&arr[i],&arr[larger]);
adjustHeap(arr,size,larger);
}
}
void heapSort(int arr[],int heapSize){
buildHeap(arr,heapSize);
//建好堆后,堆顶就是最大值了,现在把堆顶与最后一个元素交换,堆大小减一,再调整堆,每次从堆顶取出最大值与最后一个交换。
//所以说堆排序不是稳定排序,比如堆顶为10,右下角子树为2,2,2时,会把最后一个2提到堆顶,从而改变了原来三个2的次序
for(int i=heapSize;i>1;i--){
int tmp = arr[1];
arr[1]=arr[i];
arr[i]=tmp;
heapSize--;
adjustHeap(arr,heapSize,1);
}
}
inline int parent(int i){
return i/2;
}
void swap(int *a,int *b){
int tmp = *a;
*a = *b;
*b = tmp;
}
//void heapIncreaseKey(int arr[],int index,int newVal){
//
// if(arr[index]>newVal)return;
//
// arr[index]=newVal;
//
// while(index>1&&arr[parent(index)]<arr[index]){
//
// swap(&arr[parent(index)],&arr[index]);
//
// index = parent(index);
//
// }
//}
int main(int argc, char* argv[])
{
int num[]={0,-3,11,23,45,6,43,65,43,75,65,32,77,32,12
};
int length = sizeof(num)/sizeof(int) - 1;
heapSort(num,length);
printArr(num,length);
return 0;
}