精华内容
下载资源
问答
  • 怎么快速求出中位数
    千次阅读
    2021-01-29 04:53:38

    中位数:中位数是一组数字中的中间数。此代码计算包含数字的列表的中位数:

    我们定义一个数字列表并计算列表的长度。要查找中位数,我们首先使用sort()函数按升序排序列表。

    现在我们通过检查剩余数量来检查数字是偶数还是奇数。如果数字是偶数,我们在列表中找到2个中间元素并获得它们的平均值以将其打印出来。但如果数字是奇数,我们在列表中找到中间元素并将其打印出来。

    # Python program to print

    # median of elements

    # list of elements to calculate median

    n_num = [1, 2, 3, 4, 5]

    n = len(n_num)

    n_num.sort()

    if n % 2 == 0:

    median1 = n_num[n//2]

    median2 = n_num[n//2 - 1]

    median = (median1 + median2)/2

    else:

    median = n_num[n//2]

    print("Median is: " + str(median))

    输出:Median is: 3

    更多相关内容
  • O(n)的时间复杂度求中位数

    千次阅读 2020-09-26 14:45:14
    在开始O(n)时间复杂度求中位数之前,先手写一下快速排序。 快速排序的实现 Reference: 快速排序|菜鸟教程 白话经典算法系列之六 快速排序 快速搞定 快速排序的原理 如果想正序排序一个序列: 从序列中找到一个 ...

    O(n)的时间复杂度求中位数

    O(n)中位数问题是指:在O(n)的时间复杂度内找到一个无序序列的中位数。

    在开始O(n)时间复杂度求中位数之前,先手写一下快速排序。

    快速排序的实现

    Reference:
    快速排序|菜鸟教程
    白话经典算法系列之六 快速排序 快速搞定

    快速排序的原理

    如果想正序排序一个序列:

    1. 从序列中找到一个 基准数
    2. 分区:将序列中比基准数大的数字都放到基准数的右边,将序列中比基准数小的数字都放在基准数的左边。
      • 此时,序列被分成了三部分: 左序列 + 基准数 + 右序列
      • 实现2的方法可以是 挖坑法
    3. 对左序列和有序列进行排序即可(递归),直到左/右序列长度为1

    快速排序的复杂度

    1. 时间复杂度:
      • 最好:O(nlogn)
      • 最坏:O(n^2)
      • 平均:O(nlogn)
    2. 空间复杂度:O(nlogn)
    3. 稳定性:不稳定

    快速排序的实现1

    void quick_sort(int a[], int left, int right){
        if (left >= right){
            return;
        }
        int l = left, r = right;
        int x = a[left]; // 选取当前序列最左边的数字为基准数
    
        while (l < r){
            while (l < r && a[r] >= x){
                r --;
            }
            if (l < r){
                a[l] = a[r];
                l ++;
            }
            while (l < r && a[l] < x){
                l ++;
            }
            if (l < r){
                a[r] = a[l];
                r ++;
            }
        }
        a[l] = x;
        quick_sort(a, left, l - 1);
        quick_sort(a, l + 1, right);
    }
    
    • 每一次快排都会确定一个位置,这个位置是l,大小是基准数
    • 如果我们想每一次都知道 快速排序确定的位置 ,那么可以写一个partition函数。(事实上,这是在为O(n)解决中位数问题做铺垫。)

    快速排序的实现2——partition函数

    int partition(int a[], int l, int r){
        int x = a[l];
        while (l < r){
            while (l < r && a[r] >= x){
                r --;
            }
            if (l < r){ 
                a[l] = a[r];
                l ++;
            }
            while (l < r && a[l] < x){
                l ++;
            }
            if (l < r){
                a[r] = a[l];
                r --;
            }
        }
        a[l] = x;
        return l;
    }
    
    void Q_sort(int a[], int l, int r){
        if (l < r){
            int index = partition(a, l, r);
            Q_sort(a, l, index-1);
            Q_sort(a, index+1, r);
        }
    }
    
    • partiton()负责将获得每一次进行步骤2:分区得到的基准数在最终递增序列中的 位置

    • Q_sort()中的index就是该位置。根据该位置将序列分为左右序列。

    有了partition函数,就可以实现O(n)时间复杂度找中位数的工作了。

    基于partition函数的O(n)中位数

    显然,如果没有O(n)的限制,那么一个直白的想法是:将无序序列排序,然后输出序列的 n/2个位置 的元素。

    • n是序列的长度。
    • 其实,对于中位数应该分情况讨论:
      • n 是奇数时,中位数是a[n/2]
      • n 是偶数时,中位数是(a[n/2] + a[n/2 - 1]) / 2.0

    上述算法的时间复杂度是O(nlogn)

    考虑到,对于partition函数,每一个可以确定一个位置! 那么,假设这个位置是index,那么对于中位数的位置pos:

    • 如果index = pos,显然,找到了中位数a[index]
    • 如果index > pos,显然,中位数位于区间[l, index-1]
      • 此时,只需对区间[l, index-1]再次进行partition操作即可。
    • 如果index < pos,显然,中位数位于区间[index+1, r]
      • 同上。

    根据上述思想,编写函数getMidNumber():

    int getMidNumber(int a[], int l, int r, int pos){
        while (true){
            int index = partition(a, l, r); // 获得基准数的位置
            if (index == pos){
                return a[index];
            }else if (index > pos){ // 只需要在[l, index-1]区间内找pos位置即可
                r = index - 1;
            }else { // 只需要在[index, r]区间内找pos位置即可
                l = index + 1;
            }
        }
        return -1; // 一般程序不会到这里
    }
    
    • 其中,pos的含义是中位数的位置:
      • 当序列长度为奇数时,pos = n/2
      • 当序列长度为偶数时,pos = n/2 或 n/2 - 1

    比如,可以编写如下代码测试:

    int main(){
        int a[] = {10, 8, 3, 5, 6, 2, 1, 7, 9, 4};
        int aLen = sizeof(a) / sizeof(int);
    
        if (aLen&1){
            cout << "Mid= " << getMidNumber(a, 0, aLen-1, aLen/2) << endl;
        }else{
            cout << "Mid= " << (getMidNumber(a, 0, aLen-1, aLen/2) + getMidNumber(a, 0, aLen-1, aLen/2-1)) / 2.0 << endl;
        }
    
        return 0;
    }
    
    • aLen是序列a的长度。

    时间复杂度分析

    最坏:O(n^2)

    • 假设一种极端情况,每一次选取的基准数都是序列中最小的那个数字,因此partition函数会依次返回0,1,2...n/2,每一次partition函数都需要O(n)的时间复杂度。因此,最坏的时间复杂度为O(n^2)

    最好: O(n)

    • 假设一种完美情况,第一次得到的基准数就是中位数,那么只需要执行一次partition函数,因此时间复杂度是O(n)

    平均: O(n)
    数学不好,证明不会。据 他们 说该算法的 期望 时间复杂度是O(n)
    这好像是涉及 主定理MasterTheorem。搜了好多网页博客也没看懂。

    Reference:
    主定理 Master Theorem

    拓展:找序列中第K大的数字

    其实找中位数就是找序列中第n/2大的数字。

    因此找需要调用getMidNumber(a, 0, aLen-1, k)即可找到序列中第k大的数字了。

    大佬的一种更简洁的写法

    O(n)求中位数和第k大数


    2020.9.26 14:41 周六

    展开全文
  • Python实现求中位数

    千次阅读 2020-08-25 16:22:35
    使用python的内置方法list.sorted()对序列进行排序取中位数 实现 设数据为test: #作者:FarryNiu test = [5,5,6,4,5,4,7,1,10,2,11,10,10] #对test进行升序排列 print(sorted(test)) #偶数 if len(test)%2 == 0: ...

    方法

    使用python的内置方法list.sorted()对序列进行排序取中位数

    实现

    设数据为test:

    #author:FarryNiu
    test = [5,5,6,4,5,4,7,1,10,
    展开全文
  • 从海量数据中找出中位数

    千次阅读 2020-03-14 18:51:32
    题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。只写思路即可(内存限制为 2G的意思就是,可以使用2G的空间来运行程序,而不考虑这台机器上的其他软件的占用内存)。 关于中位数:...

    题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。只写出思路即可(内存限制为 2G的意思就是,可以使用2G的空间来运行程序,而不考虑这台机器上的其他软件的占用内存)。

    关于中位数:数据排序后,位置在最中间的数值。即将数据分成两部分,一部分大于该数值,一部分小于该数值。中位数的位置:当样本数为奇数时,中位数=(N+1)/2 ; 当样本数为偶数时,中位数为N/2与1+N/2的均值(那么10G个数的中位数,就第5G大的数与第5G+1大的数的均值了)。

    分析:明显是一道工程性很强的题目,和一般的查找中位数的题目有几点不同。

    1. 原数据不能读进内存,不然可以用快速选择,如果数的范围合适的话还可以考虑桶排序或者计数排序,但这里假设是32位整数,仍有4G种取值,需要一个16G大小的数组来计数。
    2. 若看成从N个数中找出第K大的数,如果K个数可以读进内存,可以利用最小或最大堆,但这里K=N/2,有5G个数,仍然不能读进内存。
    3. 接上,对于N个数和K个数都不能一次读进内存的情况,《编程之美》里给出一个方案:设k<K,且k个数可以完全读进内存,那么先构建k个数的堆,先找出第0到k大的数,再扫描一遍数组找出第k+1到2k的数,再扫描直到找出第K个数。虽然每次时间大约是nlog(k),但需要扫描ceil(K/k)次,这里要扫描5次。

    解法:首先假设是32位无符号整数。
    1.读一遍10G个整数,把整数映射到256M个区段中,用一个64位无符号整数给每个相应区段记数。
    说明:整数范围是0 - 2^32 - 1,一共有4G种取值,映射到256M个区段,则每个区段有16(4G/256M = 16)种值,每16个值算一段, 0~15是第1段,16~31是第2段,……2^32-16 ~2^32-1是第256M段。一个64位无符号整数最大值是0~8G-1,这里先不考虑溢出的情况。总共占用内存256M×8B=2GB。
    2.从前到后对每一段的计数累加,当累加的和超过5G时停止,找出这个区段(即累加停止时达到的区段,也是中位数所在的区段)的数值范围,设为[a,a+15],同时记录累加到前一个区段的总数,设为m。然后,释放除这个区段占用的内存。
    3.再读一遍10G个整数,把在[a,a+15]内的每个值计数,即有16个计数。
    4.对新的计数依次累加,每次的和设为n,当m+n的值超过5G时停止,此时的这个计数所对应的数就是中位数。

    总结:
    1.以上方法只要读两遍整数,对每个整数也只是常数时间的操作,总体来说是线性时间。
    2. 考虑其他情况。若是有符号的整数,只需改变映射即可。若是64为整数,则增加每个区段的范围,那么在第二次读数时,要考虑更多的计数。若过某个计数溢出,那么可认定所在的区段或代表整数为所求,这里只需做好相应的处理。噢,忘了还要找第5G+1大的数了,相信有了以上的成果,找到这个数也不难了吧。
    3. 时空权衡。花费256个区段也许只是恰好配合2GB的内存(其实也不是,呵呵)。可以增大区段范围,减少区段数目,节省一些内存,虽然增加第二部分的对单个数值的计数,但第一部分对每个区段的计数加快了(总体改变??待测)。
    4. 映射时尽量用位操作,由于每个区段的起点都是2的整数幂,映射起来也很方便。

    展开全文
  • 若数组有奇数个元素,中位数是a[(n-1)/2];若数组有偶数个元素,中位数为a[n/2-1]和a[n/2]两个数的平均值。这里为方便起见,假设数组为奇数个元素。 思路一:把无序数组排好序,取出中间的元素。时间复杂度取决于...
  • 无序数组的中位数(c语言版本)

    千次阅读 2019-03-22 16:06:41
    在面试时,会经常被问道,如何求解一个无序数组的中位数?很多人往往都会第一感觉就是,先将该数组排序,然后找最中间的那个数,但是这种思路通常的时间复杂度最好是O(nlogn),更糟的情况下会到O(n^2),并不是最优...
  • 大数据查找中位数

    千次阅读 2020-12-28 21:24:25
    前两天同学面试遇到的一道题,大数据怎么找出中位数。大数据 --> 所有数据不能一下子读入内存中位数 --> 需要遍历所有数据1. 题目在一个大文件中有100亿个32位整数,乱序排列,要求找出中位数;内存限制为512M...
  • 快速中位数的算法

    万次阅读 2019-07-14 07:35:59
    众所周知,quick sort的时间复杂度为O(N*log(N)),利用quick sort的原理可以实现经典的找任意...找了一下快速计算中位数的方法,找到一篇有趣的报告:“Fast Median Search: an ANSI C implementation”。这篇报告提...
  • 1.一个序列的中位数(c++)

    千次阅读 2019-07-12 02:45:36
    2、能够得到这个序列的中位数 中位数定义: #1.如果元素个数是偶数,返回已排序序列最中间的两个数字的平均数 #2.如果元素个数是奇数,返回已排序序列中间那个数 二、分析 能够看到该题的标记是hard,显...
  • 前言中位数是一个可将数值集合划分为相等的上下两部分的一个数值。如果列表数据的个数是奇数,则列表中间那个数据就是列表数据的中位数;如果列表数据的个数是偶数,则列表中间那2个数据的算术平均值就是列表数据的...
  • 算法: 快速求中位数(第k大数)

    千次阅读 2017-04-02 22:19:37
    #include #include int partition(int *a,int l,int r) { int i=l-1; int j=r,temp; int x=a[r]; while(1) { while(a[++i]); while(x[--j]) if(j==l) break; if(i>=j) ... temp=a
  • bfptr算法(即中位数中位数算法)

    万次阅读 多人点赞 2018-08-25 22:35:16
    BFPRT算法是解决从n个数中选择第k大或第k小的这个经典问题的著名算法,但很多人并不了解其细节。本文将首先介绍求解这个第k小数字问题的几个思路,然后重点介绍在最坏情况下复杂度仍然为O(n)的BFPRT算法。 一 ...
  • 快速排序和寻找中位数复杂度分析

    千次阅读 2019-02-20 09:45:10
    之所以,起“快速排序和寻找中位数”这个题目,并不是因为寻找中位数的时候使用了快速排序,而是这两个算法使用了一个同一个预处理结构 —— 划分,然后都是递归解决!中位数的也是根据一个数把原来的数划分一下,...
  • 【数组】- 如何C++数组的中位数

    千次阅读 2021-01-01 11:27:02
    那么,今天我们就来讨论,怎么使用冒泡排序的方法,数组元素的中位数? 案例 题目描述 中位数指的是一组数,如果按照大小排序排好后最中间的那个数的值,如果有偶数个元素,那么就是最中间两个数的平均数。 比如:...
  • 给一个无序数组array和数组长度n,找其中的中位数(这里考虑n为奇数) Sample: ***** Input: ***** @[@(500),@(120),@(7),@(220),@(3),@(8),@(4),@(200),@(100) ***** Output: ***** 100 解法一:将数组...
  • 在Python中查找列表的中位数

    千次阅读 2020-12-28 21:56:55
    Python 3.4有statistics.median :返回数字数据的中位数(中间值)。当数据点数为奇数时,返回中间数据点。 当数据点的数量是偶数时,通过取两个中间值的平均值来插值中值:>>> median([1, 3, 5]) 3 >>...
  • 查找中位数(java 快速排序)

    千次阅读 2016-10-31 16:14:39
    对于有限的数集,可以通过把所有观察值高低排序后找正中间的一个作为中位数。如果观察值有偶数个,通常取最中间的两个数值的平均数作为中位数。 java代码:import java.util.*; /** * @version 1.0 * @author ...
  • C语言找中位数(一位数组)

    千次阅读 多人点赞 2021-10-19 00:49:15
    题目如下 代码如下 #include<stdio.h> int main() { int n; scanf("%d",&n); int a[n],i,j,t; for(i=0;i<n;i++) scanf("%d",&a[i]); for(i=0;i<n-1;i++){//冒泡排序将数组...a[j]=t..
  • 对于有限的数集,可以通过把所有观察值高低排序后找正中间的一个作为中位数。如果观察值有偶数个,则中位数不唯一,通常取最中间的两个数值的平均数作为中位数中位数寻找的快速算法 一般寻找中位数可以先将数组...
  • 先理解快速排序。 int partition(int L[],int low,int high) { int i,num=low; for(i=low+1;i<=high;i++) { if(L[i]<L[low]) { swap(&L[i],&L[num+1]); num++; } } swap(&L...
  • C++ 查找中位数

    千次阅读 2020-05-11 18:08:17
    2.已知中位数 要求左边小于(大于)中位数,右边大于(小于)中位数,且左边数列大小等于右边数列大小 。 而对左边数列或者右边数列数值的排列顺序无要求。 所以,我们可以采用优先队列进行解决。 代码实现 #include...
  • 代码实现三个数中的中位数

    千次阅读 2019-07-14 18:21:41
    1.中位数举例 给定一组数arr1 = [1,3,0,2,6](奇数的情况)其中位数 对arr1根据数值大小重新排列:arr1_new = [0,1,2,3,6] 因此,arr1的中位数为2(2在中间位置) 给定一组数arr2 = [1,3,0,2,6,5](偶数的情况...
  • 快速查找中位数(期望O(N)的算法)

    千次阅读 2019-02-24 20:48:41
    类似于快速排序那种,只不过另加处理一番。 附上代码: #include&lt;bits/stdc++.h&gt; using namespace std; const int maxn=1e2+5; int n,a[maxn]; double select_middle(int beg,int end) { if(n==1)...
  • 快速选择无序数列的中位数

    千次阅读 2018-11-03 19:16:07
    设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个)作为关键数据,然后将所有比它小的都放到它前面,所有比它大的都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速...
  • 关于区间中位数

    千次阅读 2019-10-23 20:45:03
    区间,求出他们的中位数。 题解 这个ider先在这里占坑吧,毕竟感觉这个思路挺好的。 我们可以一开始把整个序列排序,然后对排序后的数组链表化,并且求出每个点在链表中的下标。 那么对于固定的 l l l ,...
  • 查找中位数(分治策略)

    千次阅读 多人点赞 2020-03-30 17:30:48
    要找一个数组的中位数,最简单的方法当然是将数组排序,但快速排序的时间复杂度也需要 O(nlogn),我们可以寻找更快的算法来解决。首先对于一个长度为n的有序数组a[n],若n为偶数, 则中位数为(a[n/2]+a[n/2-1])/2...
  • 一个无序数组的中位数

    千次阅读 2017-08-04 23:13:05
    问题描述一个无序数组的中位数。 如:{2,5,4,9,3,6,8,7,1}的中位数为5,{2,5,4,9,3,6,8,7,1,0}的中位数为4和5。 要求:不能使用排序,时间复杂度尽可能低。 提示:考虑堆或者快排思想解决方法1:堆思路1: 分析...
  • 快速排序(基准是中位数

    千次阅读 2017-01-02 11:46:33
    简介: 快排相比冒泡等相对较快,是因为其是跳跃式交换(快,要根据数据量等)下面算法介绍: ①根据数据量,若大于cutoff,则用快排,反之用插入排序 ②先找基准(这里采用中位数),并将基准放在Right-1的位置...
  • 数组的平均数,中位数,众数

    千次阅读 2017-12-28 19:37:42
    题目给定一个长度为100的整型数组。...输入:81 2 3 9 9 4 0 6输出:中位数:3.500000平均数:4.250000众数:9.000000代码如下:#include//冒泡排序void paixu(int a[],int n){ int i,j,t; for(i=0;i
  • 100亿个数的中位数

    千次阅读 2019-03-15 23:10:14
    给定100亿个无符号的乱序的整数序列,如何求出这100亿个数的中位数中位数指的是排序后最中间那个数)。 2、解题思路一 一个无符号整数的大小为4B,则100亿个数的大小为40GB,如果内存够大的话可以对这100亿个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 474,600
精华内容 189,840
热门标签
关键字:

怎么快速求出中位数

友情链接: yangqiu.zip