堆排序思想:利用堆(大顶堆/小顶堆)的性质,对堆的性质进行维护,利用这个性质进行建堆,然后利用堆顶为最大值或最小值的性质,顶堆元素与堆尾元素进行交换,交换后 剔除已经为最大值的堆尾元素,重新对堆顶进行堆的性质维护。 即可重复执行进行排序。
堆排序代码实现:
//堆的性质维护
void keepHeapify(int nums[], int i, int size){
int father = i; //把 i 作为父节点
int lson = i * 2 + 1; //左子节点
int rson = i * 2 + 2; //右子节点
if( lson < size && nums[lson] >nums[father])
father = lson;
if( rson < size && nums[rson] >nums[father])
father = rson;
if( father != i){
swap(nums[i],nums[father]); //使假设的父节点的值交换为最大值
keepHeapify(nums,father,size); //把被改变的子节点 作为父节点重新进行一次堆性质的维护
}
}
//利用堆的性质建堆
void createHeapify(int nums[], int size){
for(int i = size/2 ; i>=0; --i) // size / 2 为堆的最后一个父节点
keepHeapify(nums,i,size);
}
//排序
void sort(int nums[], int last){
for(int i = last; last >= 0; --last){
swap(nums[0], nums[last]); //把为最大值的堆顶交换到堆尾
keepHeapify(nums,0,last); //重新对堆的性质进行维护(剔除刚刚被交换为最大值的堆尾)
}
}
int main(int argc, char** argv) {
int nums[] = {4,6,7,8,4,2,6,3,4,20,6,7,3,19,33,11,23,7,5,5,3,3,56,7};
int n = sizeof(nums) / sizeof(nums[0]);
createHeapify(nums, n);
sort( nums, n - 1);
for(int i = 0;i < n;i++){
cout<<nums[i]<<" ";
}
return 0;
}
堆top排序思想:由堆排序的思想可知,每一次的排序,都是把为最大值堆顶元素交换到堆尾,然后剔除堆尾重新进行下一次的排序。 相当于从堆尾开始,依次填充最大值,所以我们要得到第几大值,只需要排序几次,不需要对整个数组进行堆排序,节约执行时间。
堆top排序代码实现:
//堆的性质维护
void keepHeapify(int nums[], int i, int size){
int father = i; //把 i 作为父节点
int lson = i * 2 + 1; //左子节点
int rson = i * 2 + 2; //右子节点
if( lson < size && nums[lson] >nums[father])
father = lson;
if( rson < size && nums[rson] >nums[father])
father = rson;
if( father != i){
swap(nums[i],nums[father]); //使假设的父节点的值交换为最大值
keepHeapify(nums,father,size); //把被改变的子节点 作为父节点重新进行一次堆性质的维护
}
}
//利用堆的性质建堆
void createHeapify(int nums[], int size){
for(int i = size/2 ; i>=0; --i) // size / 2 为堆的最后一个父节点
keepHeapify(nums,i,size);
}
//排序
void sort(int nums[], int last, int aim){
for(int i = last; last >= aim; --last){
swap(nums[0], nums[last]); //把为最大值的堆顶交换到堆尾
keepHeapify(nums,0,last); //重新对堆的性质进行维护(剔除刚刚被交换为最大值的堆尾)
}
}
int main(int argc, char** argv) {
int nums[] = {4,6,7,8,4,2,6,3,4,20,6,7,3,19,33,11,23,7,5,5,3,3,56,7};
int n = sizeof(nums) / sizeof(nums[0]);
createHeapify(nums, n);
sort( nums, n - 1, n-k); //k代表第几大元素
for(int i = 0;i < n;i++){
cout<<nums[i]<<" ";
}
return nums[n-k];
}