堆排序查找前N个最大数和二分查找算法

先了解堆排序概念:堆排序利用了大根堆(或小根堆)堆顶记录的关键字最大(或最小)这一特征,使得在当前无序区中选取最大(或最小)关键字的记录变得简单。

(1)用大根堆排序的基本思想

① 先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区

② 再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换,由此得到新的无序区R[1..n-1]和有序区R[n],且满足R[1..n-1].keys≤R[n].key

③由于交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆。然后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换,由此得到新的无序区R[1..n-2]和有序区R[n-1..n],且仍满足关系R[1..n-2].keys≤R[n-1..n].keys,同样要将R[1..n-2]调整为堆。

……

直到无序区只有一个元素为止。

(2)大根堆排序算法的基本操作:

① 初始化操作:将R[1..n]构造为初始堆;

② 每一趟排序的基本操作:将当前无序区的堆顶记录R[1]和该区间的最后一个记录交换,然后将新的无序区调整为堆(亦称重建堆)。

时间复杂度O(N*logN)

#include <iostream>
#include <string>
#include <vector>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

using namespace std;

//创建大根堆,即父节点大于两个子节点
void MaxHeapCreate(int array[],int n,int length) {
int temp;
int maxChild;
for(temp = array[n]; 2*n+1 < length ; n = maxChild) {
maxChild = 2*n+1;
if(maxChild<length-1 && array[maxChild+1]>array[maxChild] )
maxChild++;
if( temp < array[maxChild] ) {
array[n] = array[maxChild];
array[maxChild] = temp;
} else {
break;
}
}
}

void HeapSort(int array[],int length) {
int temp;
int i;
//由底下第一个非叶子节点开始逐个往上创建大根堆,使每个节点满足大根堆
//精髓部分,这步保证堆顶为最大
for( i = length/2 -1 ; i >= 0; i--) {
MaxHeapCreate(array,i,length);
}
for( i = length-1; i > 0 ; i-- ) {
temp = array[0];
array[0] = array[i];
array[i] = temp;
MaxHeapCreate(array,0,i);
}

}

void findFirstN(int array[],int length,int result[],int n) {
int temp;
int i,j;
for( i = length/2-1 ; i>=0 ; i-- ) {
MaxHeapCreate(array,i,length);
}
for( i = length-1,j=0; j<n && i > 0 ; i--) {
result[j++] = array[0];
temp = array[0];
array[0] = array[i];
array[i] = temp;
MaxHeapCreate(array,0,i);
}
}

template<typename T>
int BinSearch(T array[],int length,T key) {
int low = 0;
int high = length - 1;
int mid=0;
if(array[low] == key)
return low;
if(array[high] == key)
return high;
while(low<=high) {
mid = low + ((high-low)/2);
if( array[mid] == key ) {
return mid;
} else if( array[mid] > key ) {
high = mid - 1;
} else
low = mid + 1;
}
if(low>high)
return -1;
}

int main()
{
 
printf("-=-=-=-=-=堆排序=-=-=-=-=-=-=-=-=-=-=\n");
int array[]={12,15,8,33,96,76,38,22,9,23};
int a_length = sizeof(array)/sizeof(int);
HeapSort(array,a_length);

while(a_length--)
printf("array[%d]=%d\n",a_length,array[a_length]);
printf("-=-=-=-=-=利用堆排序查找前n个最大元素=-=-=-=-=-=-=-=-=-=-=\n");
int array2[]={12,15,8,33,96,76,38,22,9,23};
int a2_length = sizeof(array2)/sizeof(int);
int nn=3;
int result[3];
findFirstN(array2,a2_length,result,3);
for(a2_length=0;a2_length<nn;a2_length++)
printf("result[%d]=%d\n",a2_length,result[a2_length]);
printf("-=-=-=-=-=二分查找=-=-=-=-=-=-=-=-=-=-=\n");
printf("38的位置为:%d\n",BinSearch(array2,sizeof(array2)/sizeof(int),38));

return 0;
}
    原文作者:查找算法
    原文地址: https://blog.csdn.net/wodet/article/details/16948511
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞