100题_05 查找最小的k个元素
题目:输入n个整数,输出其中最小的k个。
例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4。
例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4。
不多说了,这个题是一个老题了,最简单的办法就是用大顶堆了,每次遍历数组与堆顶元素进行比较,如果比堆顶小,就替换堆顶,继续调整为大顶堆。
代码如下:

#pragma once
#include <cstdlib>
using namespace std;
template <typename T>
class MaxHeap
{
public:
MaxHeap(int size = 10)
{
this->size = size;
data = new T[size];
cur = 0;
}
MaxHeap(T a[], int size)
{
this->size = size;
data = new T[size];
for (int i = 0; i < size; i++)
data[i] = a[i];
cur = size;
BuildHeap();
}
T RemoveMax()
{
if (IsEmpty())
throw "heap is empty";
else
{
T temp = data[0];
data[0] = data[--cur];
if (cur > 0)
ShiftDown(0);
return temp;
}
}
void ReplaceMax(const T& value)
{
if (IsEmpty())
throw "heap is empty";
else
{
data[0] = value;
ShiftDown(0);
}
}
T PeekMax()
{
if (IsEmpty())
throw "heap is empty";
else
return data[0];
}
bool Insert(const T& value)
{
if (IsFull())
return false;
else
{
data[cur++] = value;
ShiftUp(cur - 1);
return true;
}
}
bool IsFull()
{
return cur == size;
}
bool IsEmpty()
{
return cur == 0;
}
~MaxHeap()
{
delete[] data;
}
private:
int size;
int cur;
T * data;
int LeftChild(int pose) const
{
return 2*pose + 1;
}
int RightChild(int pose) const
{
return 2*pose + 2;
}
int Parent(int pose) const
{
return (pose - 1) / 2;
}
// 从pose的位置向下调整
void ShiftDown(int pose)
{
int i = pose;
int j = LeftChild(i);
T temp = data[i];
while (j < cur)
{
if (j < cur - 1 && data[j] < data[j+1])
j++;
if (temp < data[j])
{
data[i] = data[j];
i = j;
j = LeftChild(j);
}
else
break;
}
data[i] = temp;
}
void ShiftUp(int pose)
{
int tempPose = pose;
T temp = data[tempPose];
while (tempPose > 0 && data[Parent(tempPose)] < temp)
{
data[tempPose] = data[Parent(tempPose)];
tempPose = Parent(tempPose);
}
data[tempPose] = temp;
}
void BuildHeap()
{
for (int i = cur/2 -1; i >= 0; i--)
ShiftDown(i);
}
};
#include <cstdlib>
using namespace std;
template <typename T>
class MaxHeap
{
public:
MaxHeap(int size = 10)
{
this->size = size;
data = new T[size];
cur = 0;
}
MaxHeap(T a[], int size)
{
this->size = size;
data = new T[size];
for (int i = 0; i < size; i++)
data[i] = a[i];
cur = size;
BuildHeap();
}
T RemoveMax()
{
if (IsEmpty())
throw "heap is empty";
else
{
T temp = data[0];
data[0] = data[--cur];
if (cur > 0)
ShiftDown(0);
return temp;
}
}
void ReplaceMax(const T& value)
{
if (IsEmpty())
throw "heap is empty";
else
{
data[0] = value;
ShiftDown(0);
}
}
T PeekMax()
{
if (IsEmpty())
throw "heap is empty";
else
return data[0];
}
bool Insert(const T& value)
{
if (IsFull())
return false;
else
{
data[cur++] = value;
ShiftUp(cur - 1);
return true;
}
}
bool IsFull()
{
return cur == size;
}
bool IsEmpty()
{
return cur == 0;
}
~MaxHeap()
{
delete[] data;
}
private:
int size;
int cur;
T * data;
int LeftChild(int pose) const
{
return 2*pose + 1;
}
int RightChild(int pose) const
{
return 2*pose + 2;
}
int Parent(int pose) const
{
return (pose - 1) / 2;
}
// 从pose的位置向下调整
void ShiftDown(int pose)
{
int i = pose;
int j = LeftChild(i);
T temp = data[i];
while (j < cur)
{
if (j < cur - 1 && data[j] < data[j+1])
j++;
if (temp < data[j])
{
data[i] = data[j];
i = j;
j = LeftChild(j);
}
else
break;
}
data[i] = temp;
}
void ShiftUp(int pose)
{
int tempPose = pose;
T temp = data[tempPose];
while (tempPose > 0 && data[Parent(tempPose)] < temp)
{
data[tempPose] = data[Parent(tempPose)];
tempPose = Parent(tempPose);
}
data[tempPose] = temp;
}
void BuildHeap()
{
for (int i = cur/2 -1; i >= 0; i--)
ShiftDown(i);
}
};

#include "MaxHeap.h"
#include <iostream>
using namespace std;
int *min(int a[], int n, int k) // 找出数组中前k个最小的
{
MaxHeap<int> mh(k);
int i;
for (i = 0; i < k; i++)
mh.Insert(a[i]);
for (; i < n; i++)
{
int max = mh.PeekMax();
if (a[i] < max)
mh.ReplaceMax(max);
}
int *result = new int[k];
for (i = k -1; i >= 0; i--)
{
result[i] = mh.RemoveMax();
}
return result;
}
int main()
{
int a[] = {5,3,7,2,6,8,4,9,19,50,18,16};
int *x = min(a, 12, 5);
for (int i = 0; i < 5; i++)
cout<<x[i]<<' ';
cout<<endl;
delete[] x;
return 0;
}
#include <iostream>
using namespace std;
int *min(int a[], int n, int k) // 找出数组中前k个最小的
{
MaxHeap<int> mh(k);
int i;
for (i = 0; i < k; i++)
mh.Insert(a[i]);
for (; i < n; i++)
{
int max = mh.PeekMax();
if (a[i] < max)
mh.ReplaceMax(max);
}
int *result = new int[k];
for (i = k -1; i >= 0; i--)
{
result[i] = mh.RemoveMax();
}
return result;
}
int main()
{
int a[] = {5,3,7,2,6,8,4,9,19,50,18,16};
int *x = min(a, 12, 5);
for (int i = 0; i < 5; i++)
cout<<x[i]<<' ';
cout<<endl;
delete[] x;
return 0;
}

本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名小橋流水(包含链接)。如您有任何疑问或者授权方面的协商,请给我发邮件。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述