目录
(1)提出新的现实要求:如果现在由100亿个数据,我们要找出他的最小前100呢。
*****************如果采用方法2,不合理之处**********************
题目:
1,排序算法,采用效率好的堆排序。
我们直接使用堆排序。
c语言的话,我们可以写一个向下调整算法,写一个堆排序算法。
int* getLeastNumbers(int* arr, int arrSize, int k, int* returnSize){
//用堆排序来做
HeapSort(arr,arrSize);
int* retArr=(int*)malloc(sizeof(int)*k);
for(int i=0;i<k;i++)
{
retArr[i]=arr[i];
}
*returnSize=k;
return retArr;
}
2,采用堆来计算。
用c语言写的话,我们首先要写一个堆,或者写一个堆中要用到的部分:
时间复杂度;O(N+k*longN)
int* getLeastNumbers(int* arr, int arrSize, int k, int* returnSize){
//这里我们使用堆来做
HP ph; //创建一个堆。
HeapInit(&ph,arr,arrSize);
int* retArr=(int *)malloc(sizeof(int)*k); //调用完之后在外面释放
for(int i=0;i<k;i++)
{
retArr[i]=HeapTop(&ph);
HeapPop(&ph);
}
*returnSize=k; //注意这里的*号是一定要添加的,要先解引用。
HeapDestroy(&ph);
int* a=retArr;
return retArr;
}
3,特使要求下,灵活使用堆来解决实际问题。
(1)提出新的现实要求:如果现在由100亿个数据,我们要找出他的最小前100呢。
*****************如果采用方法2,不合理之处**********************
这样我们如果用第二种的话,初始化要开辟一个大概40G的空间来存储着100亿个数据,这样空间复杂度太高了,我们消耗不起,当数据很大量时,方法2时不行的,无法解决问题。
估计以下100亿个整形要多大空间:
1KB=1024byte:
1M=1024kb;
1G=1024M: 1G 大约有 1024*1024*1024大约10亿个字节
100亿个整形 要100亿*4byte 字节
400亿除以10=40
也就是说我们需要40G的空间来存放。 方法2不可以使用。
方法3:
(1)先把数组中前k个数据建成大堆
(2)然后用剩下的N-k个数与堆顶数据比较,比堆顶小的进行交换,重新向下调整调堆
时间复杂度:O(N*logk) k比较小的。这个数不大,优秀算法。
空间复杂度:O(k) 很小,算法很省空间。优秀算法。
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
void Swap(int* px, int* py);
void AdjustDown(int* a, int n, int parent);
void Swap(int* px, int* py)
{
int tmp = *px;
*px = *py;
*py = tmp;
}
void AdjustDown(int* a, int n, int parent)
{
int child = parent * 2 + 1;
while (child < n)
{
if (child + 1 < n && a[child + 1] > a[child])
{
++child;
}
if (a[child] > a[parent])
{
Swap(&a[child], &a[parent]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
int* getLeastNumbers(int* arr, int arrSize, int k, int* returnSize){
//用堆来做
if(k==0)
{
*returnSize=0;
return NULL;
}
if(k>=arrSize)
{
*returnSize=k;
return arr;
}
int*retArr=(int*)malloc(sizeof(int)*k);
//建堆: 前k个数建立 大堆:
for(int i=0;i<k;i++) //取前k个数据准备建堆。
{
retArr[i]=arr[i];
}
for(int j=(k-1-1)/2;j>=0;j--) // 建堆
{
AdjustDown(retArr,k,j);
}
//剩下的N-k个数,与堆顶数据比较,比堆顶小,进堆
for(int i=k;i<arrSize;i++)
{
if(arr[i]<retArr[0])
{
retArr[0]=arr[i];
AdjustDown(retArr,k,0);
}
*returnSize=k;
}
return retArr;
}