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。
不多说了,这个题是一个老题了,最简单的办法就是用大顶堆了,每次遍历数组与堆顶元素进行比较,如果比堆顶小,就替换堆顶,继续调整为大顶堆。
代码如下:
View Code
#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);
}
};
View Code
#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 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名小橋流水(包含链接)。如您有任何疑问或者授权方面的协商,请给我发邮件。