码迷,mamicode.com
首页 > 编程语言 > 详细

查找数组中第i小的元素

时间:2015-03-14 11:08:15      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:查找数组中第i小元素

        查找并输出数组中第i小的元素,这样的题目我们可以先对数组进行排序,然后输出相对应的第i小的元素;还有另外一种方法,一种解决选择问题的分治算法,该算法是以快速排序算法为模型的,与快速排序一样,我们仍然将输入数组进行划分,但与快速排序不同的是,快速排序会递归处理划分的两边,而该选择方法select只处理划分的一边。这一差异会在性能分析中体现出来:快速排序的期望运行时间为O(nlog(n)),而select的选择期望运行时间是O(n)。


1、对数组进行排序,然后输入第i小的元素,这里排序算法用的是插入排序。

#include <iostream>

using namespace std;

int select(int a[], int n, int i);

int main(void)
{
    int a[5] = {4, 67, 8, 2, 3};

    cout<<select(a, 5, 4)<<endl;

    return 0;
}

static void InsertSort(int a[], int n)
{
    int i, j;

    for(i = 1; i < n; i++)
    {
        int x = a[i];
        for(j = i; j >= 0 && a[j-1] > x; j--)
            a[j] = a[j-1];
        a[j] = x;
    }
}

int select(int a[], int n, int i)
{
    InsertSort(a, n);

    return a[i-1];
}

2、递归进行选择数组中第i小的元素,select函数运行过程如下:刚开始检查递归的基本情况,当a[]包含只有一个元素时,i必须等于1,直接返回。其他情况下,就会调用Partition函数,将数组划分为两个子数组(可能为空的),a[left..j-1]和a[j+1..right],使得a[left..j-1]中每个元素都小于等于a[j],而a[j]小于a[j+1..right]中的每个元素。与快速排序一样,我们称a[j]为主元,接着计算子数组内a[left..j]中的元素个数k,即处于划分的低区的元素个数加1。然后检查a[j]是否是第i小的元素,如果是接下来直接返回,否则的话确定第i小的元素落在a[left..j-1]和a[j+1..right]两个子数组中的哪一个。如果i<k,则要查找的元素落在了划分的低区,则接下来在低区的子数组中继续递归查找;如果i>k,则要查找的元素落在了高区。我们已经知道了有k个值小于aleft..right]中的第i小的元素,即a[left..j]内的元素,所以我们要找的元素必然是a[j+1..right]中的第I-k小的元素,再进行递归查找。

#include <iostream>

using namespace std;

int select(int a[], int left, int right, int i);

int main(void)
{
    int a[5] = {4, 67, 8, 2, 3};

    cout<<select(a, 0, 4, 3)<<endl;

    return 0;
}

static void Swap(int &a, int &b)
{
    int t = a;
    a = b;
    b = t;
}
static int Partition(int a[], int left, int right)
{
    int t, i, j;

    t = a[right];
    i = left;
    for(j = left; j < right; j++)
    {
        if(a[j] < t)
            Swap(a[i++], a[j]);
    }
    Swap(a[i], a[right]);

    return i;
}

int select(int a[], int left, int right, int i)
{
    if(left == right)
        return a[left];
    int j = Partition(a, left, right);
    int k = j - left + 1;

    if(k == i)
        return a[j];
    else if(i < k)
        return select(a, left, j-1, i);
    else
        return select(a, j+1, right, i-k);
}


参考资料:

1、《算法导论》(第三版)第9章-中位数和顺序统计量



查找数组中第i小的元素

标签:查找数组中第i小元素

原文地址:http://blog.csdn.net/u012796139/article/details/44256827

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!