zoukankan      html  css  js  c++  java
  • 给一列无序数组,求出中位数并给出算法的时间复杂度

    若数组有奇数个元素,中位数是a[(n-1)/2];若数组有偶数个元素,中位数为a[n/2-1]和a[n/2]两个数的平均值。这里为方便起见,假设数组为奇数个元素。

    思路一:把无序数组排好序,取出中间的元素。时间复杂度取决于排序算法,最快是快速排序,O(nlogn),或者是非比较的基数排序,时间为O(n),空间为O(n)。这明显不是我们想要的。

    思路二:采用快速排序的分治partition过程。任意挑一个元素,以该元素为支点,将数组分成两部分,左边是小于等于支点的,右边是大于支点的。如果左侧长度正好是(n-1)/2,那么支点恰为中位数。如果左侧长度<(n-1)/2, 那么中位数在右侧,反之,中位数在左侧。 进入相应的一侧继续寻找中位数。

    //快速排序的分治过程找无序数组的中位数
    int partition(int a[], int low, int high) //快排的一次排序过程
    {
        int q = a[low];
        while (low < high)
        {
            while (low < high && a[high] >= q)
                high--;
            a[low] = a[high];
            while (low < high && a[low] <= q)
                low++;
            a[high] = a[low];
        }
        a[low] = q;
        return low;
    }
    int findMidium(int a[], int n)
    {
        int index = n / 2;
        int left = 0;
        int right = n - 1;
        int q = -1;
        while (index != q)
        {
            q = partition(a, left, right);
            if (q < index)
                left = q + 1;
            else if (q>index)
                right = q - 1;
        }
        return a[index];
    }

    思路三:将数组的前(n+1)/2个元素建立一个最小堆。然后,对于下一个元素,和堆顶的元素比较,如果小于等于,丢弃之,如果大于,则用该元素取代堆顶,再调整堆,接着看下一个元素。重复这个步骤,直到数组为空。当数组都遍历完了,(堆中元素为最大的(n+1)/2个元素,)堆顶的元素即是中位数

     1 //构建最小堆找无序数组的中位数
     2 void nswap(int& i, int& j)
     3 {
     4     i = i^j;
     5     j = i^j;
     6     i = i^j;
     7 }
     8 void minHeapify(int a[], int i, int len)
     9 {
    10     int temp;
    11     int least = i;
    12     int l = i * 2 + 1;
    13     int r = i * 2 + 2;
    14     if (l < len && a[l] < a[least])
    15         least = l;
    16     if (r < len && a[r] < a[least])
    17         least = r;
    18     if (least != i)
    19     {
    20         nswap(a[i], a[least]);
    21         minHeapify(a, least, len);
    22     }
    23 }
    24 void buildMinHeap(int a[], int len)
    25 {
    26     for (int i = (len-2) / 2; i >= 0; i--)
    27     {
    28         minHeapify(a, i, len);
    29     }
    30 }
    31 int findMidium2(int a[], int n)
    32 {
    33     buildMinHeap(a, (n + 1) / 2);
    34     for (int i = (n + 1) / 2; i < n; i++)
    35     {
    36         if (a[i] > a[0])
    37         {
    38             nswap(a[i], a[0]);
    39             minHeapify(a, 0,(n + 1) / 2);
    40         }        
    41     }
    42     return a[0];
    43 }

    ----------------------------------------------------------

     参考原文:https://blog.csdn.net/jiangyanting2011/article/details/70325215 

  • 相关阅读:
    冒泡排序-用函数写
    c#语言基础
    c#小知识点
    令人头疼的冒泡排序
    字符串 与函数
    数组 冒泡排序 打印菱形 随机生成不同的数
    if语句练习
    运算符练习
    类型转换
    C#初学
  • 原文地址:https://www.cnblogs.com/ArleneZhangfj/p/10040891.html
Copyright © 2011-2022 走看看