重载运算符 [] 实现寻找数组的第K大的元素

December 14, 2012

方法是利用快排的想法,效率O(N)


/*
 * use the method of quicksort. The time efficiency is 
 * O(N).
 * 
 * */
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <iomanip>

using namespace std;

class Array
{
public:
    friend istream & operator >> (istream & input, Array & a);
    friend ostream & operator << (ostream & outpu, Array & a);
    int operator [] (int p);
    void exchange(int &s, int &t);
    int partition(int *p, int l, int r);
    int k_element(int *p, int l, int r, int k);
    int getlen(){return len;}
private:
    int *a;
    int len;
};

int Array::operator [] (int p)
{
    return k_element(a, 0, len-1, p);
}

int Array::k_element(int *p, int l, int r, int k)
{
    if (l < r)
    {
        int q = partition(p, l, r);
        if (q + 1 == k)
            return p[q];
        else if (q + 1 > k)
            return k_element(p, l, q-1, k);
        else 
            return k_element(p, q+1, r, k); //这个地方尤其要注意,应该还是k,而不是k-q-1!
    }
    else return p[l];
}

ostream & operator << (ostream & output, Array & array)
{
    for (int i = 0; i < array.len; ++i)
        output << setw(3) << array.a[i]; 
    output << endl;
    return output;
}

istream & operator >> (istream & input, Array & array)
{
    cout << "intput the length of Array: ";
    input >> array.len;
    array.a = new int[array.len+1];
    for (int i = 0; i < array.len; ++i)
        input >> array.a[i];
    return input;
}

void Array::exchange(int &s, int &t)
{
    int temp;
    temp = s; s = t; t = temp; 
}

int Array::partition(int *p, int l, int r)
{
    int i = (l+r)/2, j;
    exchange(p[i], p[r]);
    int store = l;
    for (j = l; j < r; ++j)
    {
        if (p[j] >= p[r])
        {
            exchange(p[j], p[store]);
            store++;
        }
    }
    exchange(p[r], p[store]);
    return store;
}

int main(void)
{
    Array array;

    freopen("in", "r", stdin);

    cin >> array;
    cout << array;
    for (int i = 0; i < array.getlen(); ++i)
        cout << i+1 << "-th: " << array[i+1] << endl;
    cout << endl;

    return 0;
}

写的过程中还是出现了一些错误,以后要认真,尤其是细节,不能想当然,要仔细一点。

comments powered by Disqus