平均期望为线性时间的选择算法

从一组无序数据中选择出第i小的元素,采用了快速排序的思想。

#include <iostream>
#include <algorithm>
using namespace std;

int partition(int a[], int l, int r){
    int key = a[l];
    int i=l;
    swap(a[l],a[r]);
    for(int j=l;j<r;j++)
        if(a[j]<key) swap(a[i++],a[j]);
    swap(a[i],a[r]);
    return i;
}
int select(int a[],int l,int r,int i)
{
    if(l==r)
        return a[l];
    int q=partition(a,l,r);
    int k=q+1-l;
    if(k==i)
        return a[q];
    else if(k>i)
        return select(a,l,q-1,i);
    else
        return select(a,q+1,r,i-k);
}
int main()
{
    int a[6] = {5,9,11,23,10,44};
    cout<<select(a,0,8,4);//获取a中第4小的元素,即11.
}

随机化版本

#include <iostream>
#include <algorithm>
using namespace std;

int rand_partition(int a[], int l, int r){
    int q=l+rand()%(r+1-l);
    int key = a[q];
    int i=l;
    swap(a[q],a[r]);
    for(int j=l;j<r;j++)
        if(a[j]<key) swap(a[i++],a[j]);
    swap(a[i],a[r]);
    return i;
}
int select(int a[],int l,int r,int i)
{
    if(l==r)
        return a[l];
    int q=rand_partition(a,l,r);
    int k=q+1-l;
    if(k==i)
        return a[q];
    else if(k>i)
        return select(a,l,q-1,i);
    else
        return select(a,q+1,r,i-k);
}
int main()
{
    int a[6] = {5,9,11,23,10,44};
    cout<<select(a,0,8,4);//获取a中第4大的元素,即11.
}
时间: 2024-08-02 02:07:18

平均期望为线性时间的选择算法的相关文章

第九章 中位数和顺序统计量 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

期望为线性时间的选择算法

randomized_select函数的期望运行时间是Θ(n),这里假设输入数据都是互异的.它返回数组A[p, r]中第i小的元素.该函数最坏情况运行时间为Θ(n2),即使是找最小元素也是如此,以为在每次划分时可能极不走运地总是按余下的元素中最大的来进行划分,而划分操作需要Θ(n)时间.我们也将看到该算法有线性的期望运行时间,又因为它是随机化的,所以不存在一个特定的会导致其最坏情况发生的输入数据. 输入:数组A,整数i(i不大于数组的个数). 输出:数组A中第i小的元素. 期望运行时间:Θ(n)

期望为线性时间的选择算法RANDOM_SELECT

1 #include<iostream> 2 #include<ctime> 3 using namespace std; 4 void swap(int *a, int *b) 5 { 6 int *c = a; 7 a = b; 8 b = c; 9 } 10 int Partition(int *A, int p, int r)// 划分 11 { 12 int x = A[r]; 13 int i = p - 1; 14 for (int j = p; j < r;

最坏情况为线性时间的选择算法

求给定输入中第k大的数的算法. 这是一个常见面试题,通常的解法也很明显,使用类似快排的思想. 每趟运行,把数组的值分成两部分,一部分比pivot大,一部分比pivot小,因为我们知道pivot在数组中的位置,所以比较k和pivot的位置就知道第k大的值在哪个范围,我们不断的进行recursion, 直到pivot就是第k大的值. 这个算法的时间预期是O(n).这里需要注意的是讲的仅限于它的预期,对于这个算法,其在最差情况下,时间复杂度则为n的平法. 参阅快速排序的无敌对手一文,我们是可以构建出一

算法导论9.2以期望线性时间做选择

#include <stdint.h> #include <time.h> #include <iostream> #ifdef __linux #include <stdio.h> #include <stdlib.h> #endif void swap(int64_t* A, uint64_t i, uint64_t j) { int64_t tmp = A[i]; A[i] = A[j]; A[j] = tmp; } int64_t par

算法导论学习之线性时间排序+排序算法稳定性终结

前面我们学习的几种排序算法都是基于比较的,对于任何输入数据他们都是适用的,其最坏的时间复杂度不会低于nlgn: 但对于一些比较特殊的输入数据,我们可以不采取比较的方法而是采用其它的方法对其进行排序,以达到线性的时间复杂度.下面就来介绍三种这样的算法:计数排序,基数排序,桶排序(因为这几种算法不常见,我只实现了计数排序,其它两种排序用伪代码表示). 一.计数排序 算法思想:给定n个位于0–k之间的数(k是一个不太大的整数),我们可以统计出每个数前面有多少个小于它的数,然后就可以直接确定这个数在数组

算法导论——lec 08 线性时间排序

之前我们介绍了几种O(nlgn)的排序算法:快速排序.合并排序和堆排序,本节我们介绍基于比较的排序算法的下界以及几个线性时间的排序算法--计数排序.基数排序.桶排序. 一. 比较排序算法的下界 1. 决策树模型:比较排序可以被抽象的视为决策树.一棵决策树是一棵满二叉树,表示某排序算法 作用于给定输入所做的所有比较. 排序算法的执行对应于遍历一条从树的根到叶结点的路径.在每个内节结点处要做比较. 要使排序算法能正确的工作,其必要条件是,n 个元素的n!种排列中的每一种都要作为决策树 的一个叶子而出

读书日记- 线性时间排序算法

在最坏情况下,任何比较排序算法都需要做O(nlgn)次比较. 然而,在指定的条件下,线性时间的排序算法可以使得排序在O(n)时间内完成. 计数排序 假设n个输入元素中的每一个都是0到k区间内的一个整数,其中k为某个整数.k=O(n)时,排序运行时间为O(n). 主要思想: 创建长度为k的数组C,将对应的输入数组A的值作为索引来统计k数组每个下标出现的次数. 代码如下: void Counting_Sort(int* intArr,int* outArr,int k,int len) { int*

线性时间排序算法

线性时间排序算法列表 线性时间排序 Name Average Worst Memory Stable Description  计数排序 (Counting Sort) n + k n + k n + k Stable Indexes using key values.  基数排序 (Radix Sort) n * k  n * k n + k Stable Examines individual bits of keys.  桶排序 (Bucket Sort) n + k n2 n * k S