100题_05 查找最小的k个元素

题目:输入n个整数,输出其中最小的k个。
例如输入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);
    }
};

 

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 *= min(a, 125);
    
for (int i = 0; i < 5; i++)
        cout
<<x[i]<<' ';
    cout
<<endl;
    delete[] x;
    
return 0;
}

posted on 2011-03-04 06:13  小橋流水  阅读(305)  评论(0编辑  收藏  举报

导航