算法导论—中位数与顺序统计量

一、选择最大值或者最小值的最优算法

对于长度为n的数组,已证找最大值或者最小值比较操作下界就是n-1。所以只需要让第一个值为初始最大值或者初始最小值,用所有的值与这个值比较,更新这个值即可。

def minimum(a):
    minNum=a[0]
    for i in range(1,len(a)):
        if minNum>a[i]:
            minNum=a[i]
    return minNum
print(minimum ([1,2,3,4,5,6,7,8,9]))

二、同时选择最大值和最小值的快速算法(成对比较)

首先设置一对初始的最大值最小值(总数个数是奇数,初始最大值最小值为第一个数,若是偶数就为前两个比较),然后剩下的数两两组对,对内比较大小,然后小的与当前最小的比,大的与当前最大的比。这样的话两个数需要比较三次。如果选择分别计算最大值最小值需要2(n-1)次比较,采用成对比较的话只需要3int(n/2)次

def minmax(a):
    k=len(a)
    if k%2==0:
        if a[0]<a[1]:
            minNum,maxNum=a[0],a[1]
        else:
            minNum,maxNum=a[1],a[0]
    else:
        minNum,maxNum=a[0],a[0]
    for i in range(2-k%2,k,2):
        if a[i]>a[i+1]:
            a[i+1],a[i]=a[i],a[i+1]
        if a[i]<minNum:
            minNum=a[i]
        if a[i+1]>maxNum:
            maxNum=a[i+1]
    return minNum,maxNum
print(minmax([1,2,3,4,5,6,7,8,9]))

三、期望时间为线性时间的选择算法—随机选择

回想一下,快速排序的时候,选择一个数(随机)为基准,左右交换将小于基准的分到左边,大于基准的分到右边的思想,然后得到这个数在数组中的位置,这样我们可以根据这个位置判断我们要的数所处的位置,逐步缩小搜索范围。

import random

def randomizedPartion(a,p,r):
    k=random.randint(p, r)
    a[k],a[r]=a[r],a[k]
    value=a[r]
    i=p-1
    for j in range(p,r):
        if a[j]<value:
            i+=1
            a[i],a[j]=a[j],a[i]
    i+=1
    a[i],a[r]=a[r],a[i]
    return i

def randomizedSelect(a,p,r,i):
    q=randomizedPartion(a,p,r)
    k=q-p+1
    if k==i:
        return a[q]
    else:
        if i<k:
            return randomizedSelect(a,p,q-1,i)
        else:
            return randomizedSelect(a,q+1,r,i-k)

lst=[2,6,3,1,5,0,7,8,4,9]
k=randomizedSelect(lst,0,len(lst)-1,10)
print(k)

四、最坏时间为线性时间的选择算法—中位数的中位数划分

基于快速排序的舍弃法,不考虑直接命中的情况的话一次平均舍弃一半的数。

select算法的思想为:首先对数组中所有的数分组,每个组的大小为奇数,然后计算每个组的中位数,然后计算所有组的中位数的中位数,获取这个中位数在数组的位置,然后比较舍弃。这样每次舍弃的下限就不是基于快速算法的0了。

def midNum(a):
    k=len(a)
    groupNum=5
    start=0
    while start<k:
        end=min(k-1,start+4)
        InsertSort(a,start,end)
        start+=5
    if k<5:
        return a[(k-1)//2]
    else:
        b=a[(groupNum//2)::groupNum]
        return midNum(b)

def InsertSort(a,start,end):
    for k in range(start+1,end+1):
        i=k
        while a[i-1]>a[i] and i>start:
            a[i-1],a[i]=a[i],a[i-1]
            i-=1
    return a

def PartionByValue(a,x):
    i=0
    j=0
    for k in range(0,len(a)):
        if a[k]<x:
            a[k],a[i]=a[i],a[k]
            i+=1
    for k in range(i,len(a)):
        if a[k]==x:
            j=k
    a[i],a[j]=a[j],a[i]
    return i

def select(a,i):
    mid=midNum(a)
    k=PartionByValue(a,mid)+1
    if i==k:
        return mid
    else:
        if i<k:
            return select(a[0:k-1],i)
        else:
            return select(a[k::],i-k)

lst=[2,6,3,1,5,0,7,8,4,9]
k=select(lst,10)
print(k)

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-09 06:47:27

算法导论—中位数与顺序统计量的相关文章

算法导论 中位数和顺序统计量(python)

第i个顺序统计量:该集合中第i小的元素(建集合排序后第i位 当然算法可以不排序) 中位数:集合中的中点元素 下中位数 上中位数 9.1最大值和最小值 单独的max或min每个都要扫一遍 n-1次比较 如果同时找max和min 要 :1.2个数相互比较 1次{每次选出2个 选n//2次} 2.大的和max比较 3.小的和min比较 找出序列为第i小的数Θ(n) 随机快速排序的运用:(可以回去看快排) 代码: import random def PARTTION(A,p,r): x = A[r] i

算法导论-中位数和顺序统计量

在一个由n个元素组成的集合中,第i个顺序统计量是该集合中第i小的元素.一个中位数是它所属集合的“中点元素”.当n为奇数时,中位数是唯一的,位于i=(n+1)/2处:当n为偶数时,存在两个中位数,分别位于i=n/2和i=n/2+1处.如果不考虑n的奇偶性,中位数总是出现在i=⌊(n+1)/2⌋处(下中位数)和i=⌈(n+2)/2⌉(上中位数). 1.最小值和最大值 在一个有n个元素的集合中,需要做n-1次(上界)比较才能找到最小值或最大值. int MiniValue(const int *A,

(转)算法导论—中位数与顺序统计量

http://m.blog.csdn.net/blog/zhangzhengyi03539 http://m.blog.csdn.net/blog/zhangzhengyi03539/46795831 一.选择最大值或者最小值的最优算法 对于长度为n的数组,已证找最大值或者最小值比较操作下界就是n-1.所以只需要让第一个值为初始最大值或者初始最小值,用所有的值与这个值比较,更新这个值即可. def minimum(a): minNum=a[0] for i in range(1,len(a)):

算法导论-------------中位数和顺序统计学

文章来自网络加课本: 本次学习的内容讨论的问题是在一个由n个不同数值构成的集合中选择第i个顺序统计量问题.主要讲的内容是如何在线性时间内O(n)时间内在集合S中选择第i小的元素,最基本的是选择集合的最大值和最小值.一般情况下选择的元素是随机的,最大值和最小值是特殊情况,书中重点介绍了如何采用分治算法来实现选择第i小的元素,并借助中位数进行优化处理,保证最坏保证运行时间是线性的O(n). 1.基本概念 顺序统计量:在一个由n个元素组成的集合中,第i个顺序统计量是值该集合中第i小的元素.例如最小值是

算法导论第九章中位数和顺序统计量(选择问题)

本章如果要归结成一个问题的话,可以归结为选择问题,比如要从一堆数中选择最大的数,或最小的数,或第几小/大的数等, 这样的问题看似很简单,似乎没有什么可研究的必要,因为我们已经知道了排序算法,运用排序+索引的方式不就轻松搞定了?但细想,排序所带来的时间复杂度是不是让这个问题无形之中变得糟糕.那算法研究不就是要尽可能避免一个问题高复杂度地解决,让那些不敢肯定有无最优解的问题变得不再怀疑,这也是算法研究者所追求的一种极致哲学.既然排序让这个问题解决的性能无法确定,那我们就抛开排序,独立研究问题本身,看

算法导论之七(中位数和顺序统计量之选择算法)

实际生活中,我们经常会遇到这类问题:在一个集合,谁是最大的元素?谁是最小的元素?或者谁是第二小的元素?....等等.那么如何在较短的时间内解决这类问题,就是本文要阐述的. 先来熟悉几个概念: 1.顺序统计量: 在一个由n个元素组成的集合中,第i个顺序统计量(order statistic)是该集合中第i小的元素.最小值是第1个顺序统计量(i=1),最大值是第n个顺序统计量(i=n).   2.中位数: 一个中位数是它所属集合的"中点元素",当n为奇数时,中位数是唯一的,位于i=(n+1

[算法导论 Ch9 中位数和顺序统计量] Selection in O(n)

1. 寻找第k大(小)的数 假设数据存储在数组a[1..n]中 首先,寻找一个数组中最大或者最小的数,因为最大(小)的数一定要比其他所有的数大(小),因此至少要比较完所有的pair才能确定,所以时间复杂度在O(n).那么寻找第k大(小)呢? 比较直观的,就是对数组中国所有的数据先进行排序,在我们这种渣渣的计算机入门选手而言,可选的有QuickSort,MergeSort和HeapSort,甚至是ShellSort等一些比较高级的方法啊...一般的代价都在O(n*logn)上,然后直接取出即可.

第九章 中位数和顺序统计量 9.2 期望为线性时间的选择算法

package chap09_Medians_and_Order_Statistics; import static org.junit.Assert.*; import java.util.Random; import org.junit.Test; public class SearchAlorithms { /** * 分割(快速排序中对数组的分割) * * @param n * @param start * @param end * @return */ protected static

【算法导论学习-016】两个已排过序的等长数组的中位数(median of two sorted arrays)

问题来源 <算法导论>P223 9.3-8: Let X[1..n] and Y[1..n] be two arrays, each containing nnumbers already in sorted order. Give an O(lgn)-time algorithm to find themedian of all 2n elements in arrays X and Y. 翻译过来即:求两个等长(n个元素)的已排序数组A和B的中位数 方案1:对两个数组进行归并直到统计到第n