最小的k个数


题目:输入n个整数,找出其中最小的k个数。例如输入4、5、1、6、2、7、3、8这8个字,则最小的4个数字是1、2、3、4。


程序代码:

#include <iostream>

void ShiftValue(int *pArray, int iNode, int iLength)
{
    int iTmp = pArray[iNode];
    int iNext = 2 * iNode + 1;

    while (iNext < iLength)
    {
        if (iNext < iLength - 1 && pArray[iNext] < pArray[iNext + 1])
        {
            iNext++;
        }

        if (iTmp < pArray[iNext])
        {
            pArray[iNode] = pArray[iNext];
            iNode = iNext;
            iNext = 2 * iNext + 1;
        }
        else
        {
            break;
        }
    }

    pArray[iNode] = iTmp;
}

void BuildHeap(int *pArray, int iLength)
{
    for (int i = (iLength - 1) / 2; i >= 0; i--)
    {
        ShiftValue(pArray, i, iLength);
    }
}

bool FindValue(int *pArray, int iLength, int iValue)
{
    for (int i = 0; i < iLength; i++)
    {
        if (pArray[i] == iValue)
        {
            return true;
        }
    }
    return false;
}

void GetLeastNumbers(int *pArray, int iLength, int k)
{
    int *pContaintor = (int *)malloc(sizeof(int) * k);
    int iIndex = 0;

    if (pArray == NULL || iLength < 0 || k < 1 || k > iLength)
    {
        return;
    }

    for (int i = 0; i < iLength && iIndex < k; i++)
    {
        if (!FindValue(pContaintor, iIndex, pArray[i]))
        {
            pContaintor[iIndex++] = pArray[i];
        }
    }

    BuildHeap(pContaintor, k);

    if (k < iLength)
    {
        for (int i = k; i < iLength; i++)
        {
            if (pArray[i] < pContaintor[0] && !FindValue(pContaintor, k, pArray[i]))
            {
                pContaintor[0] = pArray[i];
                ShiftValue(pContaintor, 0, k);
            }
        }
    }

    for (int i = 0; i < iIndex; i++)
    {
        std::cout << pContaintor[i] << " ";
    }

    std::cout << std::endl;
}

int main()
{
    int iArray[] = { 4, 4, 1, 6, 2, 7, 3, 8 };
    int iLength = 8;

    GetLeastNumbers(NULL, iLength, 8);

    system("pause");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值