zoukankan      html  css  js  c++  java
  • 寻找序列中最小的第N个元素(partition函数实现)

    Partition为分割算法,用于将一个序列a[n]分为三部分:a[n]中大于某一元素x的部分,等于x的部分和小于x的部分。

    Partition程序如下:

    long Partition (long a[], long p1, long p2)
    {//对a[p1]~a[p2]进行分割,返回分割点的序号, p1, p2分别为元组的第一   //个和最后一个元素
    long i, j;
    int x;
    i = p1;
    j = p2;
    x = a[i];
    while (i<j)
    {while ( a[j] >= x && i,j) j--;
    if (i<j) {a[i] = a[j]; i++;}
    while (a[i] <= x && i<j) i++;
    if (i<j) {a [j] = a[i]; j--;}
    }
    
    a[i] = x;
    return i;
    }

    则利用partition 函数来实现查找第n个元素的程序如下所示:

    long OrderStatistics(long a[], long p1, long p2, long k)
    {// 在a[p1]~a[p2] 中, 找出最小值,并返回值
    long p, num;
    if (k<1 || k>p2-p1+1) return -1; 
    if (p1 >= p2) return a[p1];
    //若a[p1]~a[p2] 只有一个元素,则返回该元素
    p = Partition(a, p1, p2);
    num = p-p1;
    if (k == num + 1) return a[p]; //第k小元素为分割点
    if (k <= num) return OrderStatistics(a, p1, p-1, k); //第k小元素在前部
    return OrderStatistics(a, p+1, p2, k-num-1); // 第k 小元素在后部 
    }

    Python cookbook 中给出了这一方法的python 实现, 如下所示:

    import random
    
    def select(data, n):
    # 创建一个新列表, 处理小于0的索引, 检查索引的有效性
    data = list(data)
    if n<0:
        n += len(data)
    if not 0 <= n < len(data):
        raise ValueError, "can't get rank %d out  of %d" %(n, len(data))
    # 主循环, 看上去类似于排序但不需要递归
    while True:
        pivot = random.choice(data)
        pcount = 0
        under, over = [], []
        uappend, oappend = under.append, over.append
        for elem in data:
            if elem < pivot:
                uappend(elem)
            elif elem > pivot:
                oappend(elem)
            else:
                pcount += 1
        numunder = len(under)
        if n < numunder:
            data = under
        elif n < numunder + pcount:
            return pivot
        else:
            data = over
            n -= numunder +pcount

    作者提到,也可以通过下面的简单方法实现第k个元素的查找:

    def selsor(data, n):
        data = list(data)
        data.sort()
        return data[n]

    以上两种方法都可以实现,但是“基于列表的sort方法的实现的确简单的多, 实现select也确实需要多付出一点力气, 但如果n足够大而且比较操作的开销也无法忽略的话,select就体现出它的价值了。”

  • 相关阅读:
    mysql 聚集函数 count 使用详解
    在Docker中使用kettle遇到的问题解决
    整取零存_字段级迁移工具
    快速修改MySQL字段类型
    数据仓库知识点梳理(4)
    五一节分享60多本免费AI电子书
    数据仓库知识点梳理(3)
    数据仓库知识点梳理(2)
    数据仓库知识点梳理(1)
    解决MacVim在macOS Catalina下字母显示不全的问题
  • 原文地址:https://www.cnblogs.com/siriuswang/p/4586269.html
Copyright © 2011-2022 走看看