算法练习:寻找最小的k个数

参考July的文章:http://blog.csdn.net/v_JULY_v/article/details/6370650

寻找最小的k个数
题目描述:查找最小的k个元素
题目:输入n个整数,输出其中最小的k个。
例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4。

总体思路:

取n个数字的前k个数字构建大根堆,设根顶元素为kmax,

从n-k+1开始遍历剩余的n-k个元素,取出每一个元素和大根堆根元素进行比较,如果kmax>遍历到的元素值,则kmax=遍历到的元素值,并更新大根堆。

算法时间复杂度分析:TODO

C++代码:

#include <iostream>  
#include <assert.h> 
using namespace std;
//调整根元素序号为index的子树
void MaxHeapAdjust(int arr[], int index, int len)
{
    int largeIndex = index;
    int leftChildIndex = index * 2;
    if(leftChildIndex <= len && arr[leftChildIndex] > arr[index])
    {
        largeIndex = leftChildIndex;
    }
    int rightChildIndex = index * 2 + 1;
    if(rightChildIndex <= len && arr[rightChildIndex] > arr[index] && arr[leftChildIndex] < arr[rightChildIndex])
    {
        largeIndex = rightChildIndex;
    }

    if(largeIndex != index)
    {
        int tmp = arr[index];
        arr[index] = arr[largeIndex];
        arr[largeIndex] = tmp;

        MaxHeapAdjust(arr, largeIndex, len);
    }
}

void MaxHeapBuild(int arr[], int len)
{
    for(int i=len/2; i>=1; i--)
    {
        MaxHeapAdjust(arr, i, len);
    }
}

int main()
{
    //int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
    int a[] = {8, 7, 6, 5, 4, 3, 2, 1};
    //从n个元素中查找出最小的k个元素
    const int n = 8;
    const int k = 4;
    //构建k个元素的大根堆
    int maxheap[k+1];//因为堆元素的序号从1开始,数组的序号从0开始,这里添加一个无意义的首元素maxheap[0]
    for(int i=1; i<=k; i++)
    {
        maxheap[i] = a[i-1];
    }
    MaxHeapBuild(maxheap, k);
    cout << "构建k个元素的大根堆" << endl;
    for(int i=1;i<=k;i++)
        cout << maxheap[i] << " ";
    cout << endl;

    //遍历剩下的n-k个元素,与大根堆的根元素进行判断处理
    for(int i=n-k; i<n; i++)
    {
        if(maxheap[1] > a[i])
        {
            maxheap[1] = a[i];
            MaxHeapAdjust(maxheap, 1, k);
        }
    }
    cout << "查找出的最小的k个元素为" << endl;
    for(int i=1; i<=k; i++)
        cout << maxheap[i] << " ";
    cout << endl;

    cin.get();
    cin.get();
    return 0;
}
原文地址:https://www.cnblogs.com/wenwujuncheng/p/3970448.html