舍伍德线性时间选择

算法分析与设计实验报告
第 8次实验

姓名 学号 班级
时间 12.26下午 地点 四合院
实验名称
Sherwood 型线性时间选择算法

实验目的 1)通过上机实验,要求掌握 Sherwood 型线性时间选择算法的问题描述、算法设计思想、程序设计。
实验原理
使用舍伍德型选择算法,根据不同的输入用例,能准确的输出用例中的中值,
并计算出程序运行所需要的时间
给定任意几组数据,利用舍伍德型选择算法,找出数组中的中值并输出(若 数
组为奇数个则输出中值,若数组为偶数个则输出第 n/2 小元素)。

实验步骤
① 先判断是否需要进行随机划分即(kϵ(1,n)?n>1?);
② 产生随机数 j,选择划分基准,将 a[j]与 a[l]交换;
③ 以划分基准为轴做元素交换,使得一侧数组小于基准值,另一侧数组
值大于基准值;
④ 判断基准值是否就是所需选择的数,若是,则输出;若不是对子数组
重复步骤②③④。

关键代码
template
inline void Swap(Type &a,Type &b) {
Type temp = a;
a = b;
b = temp;
}

//计算a[l:r]中第k小元素
template
Type select(Type a[],int l,int r,int k) {
static RandomNumber rnd;
while(true) {
if(l>=r) {
return a[l];
}
int i = l,
j = l + rnd.Random(r-l+1);//随机选择划分基准
Swap(a[i],a[j]);
j = r+1;
Type pivot = a[l];
//以划分基准为轴做元素交换
while(true) {
while(a[++i] while(a[--j]>pivot);
if(i>=j) {
break;
}
Swap(a[i],a[j]);
}
if(j-l+1 == k){ //第k小
return pivot;
}
//a[j]必然小于pivot,做最后一次交换,满足左侧比pivot小,右
侧比pivot大
a[l] = a[j];
a[j] = pivot;
//对子数组重复划分过程
if(j-l+1 k = k-j+l-1;//右侧:k-(j-l+1)=k-j+l-1
l = j + 1;
}
else {
r = j - 1;
}
}
}

//计算a[0:n-1]中第k小元素
//假设a[n]是一个键值无穷大的元素
template
Type select(Type a[],int n,int k) {
if(k<1 || k>n) {
cout<<"请输入正确的k!"< return 0;
}
return select(a,0,n-1,k);
}
附录:完整代码

#include
using namespace std;

//随机数类
const unsigned long maxshort=66536L;
const unsigned long multiplier=1194211693L;

测试结果
实验心得
通过这次实验,我回顾了舍伍德线性时间查找问题
本次实验实现起来的代码较长,但在之前的实验中都要求使用舍伍德产生
随机数,因此本次实验还是比较简单的。主要是掌握对随机数RandomNuber类
的理解。在实现书上代码后,我将代码改进为随机产生序列的方式,手动选择
查找的数组元素(从小到大排序后)的序号,并输出到屏幕。因此,要想找出
最大元素,直接输入查找序号为数组大小即可得,同理最小元素为序号一,因
此可以实现最值求解。
通过本次实验发现,尽管嗯多时候实验的算法内容能在书本上找到,但是
如果能加入自己的理解进行修改代码,也会有很大的收获,因为只有掌握了思
想才能进行修改。
实验得分 助教签名
const unsigned long adder=12345L;
class RandomNumber{
private:
//当前种子
unsigned long randSeed;
public:
RandomNumber (unsigned long s=0); //构造函数,默认值0表示由系统自动
产生种子
unsigned short Random(unsigned long n); //产生0:n-1之间的随机整数
double fRandom(void); //产生[0,1)之间的随机实数
};

RandomNumber::RandomNumber(unsigned long s){
if(s==0) randSeed=time(0);
else randSeed=s;
}

unsigned short RandomNumber::Random(unsigned long n){
randSeed=multiplier*randSeed+adder;
return(unsigned short)((randSeed>16)%n);
}

double RandomNumber::fRandom(void){
return Random(maxshort)/double(maxshort);
}

template
inline void Swap(Type &a,Type &b) {
Type temp = a;
a = b;
b = temp;
}

//计算a[l:r]中第k小元素
template
Type select(Type a[],int l,int r,int k) {
static RandomNumber rnd;
while(true) {
if(l>=r) {
return a[l];
}
int i = l,
j = l + rnd.Random(r-l+1);//随机选择划分基准
Swap(a[i],a[j]);
j = r+1;
Type pivot = a[l];
//以划分基准为轴做元素交换
while(true) {
while(a[++i] while(a[--j]>pivot);
if(i>=j) {
break;
}
Swap(a[i],a[j]);
}
if(j-l+1 == k){ //第k小
return pivot;
}
//a[j]必然小于pivot,做最后一次交换,满足左侧比pivot小,右侧比pivot大
a[l] = a[j];
a[j] = pivot;
//对子数组重复划分过程
if(j-l+1 k = k-j+l-1;//右侧:k-(j-l+1)=k-j+l-1
l = j + 1;
}
else {
r = j - 1;
}
}
}

//计算a[0:n-1]中第k小元素
//假设a[n]是一个键值无穷大的元素
template
Type select(Type a[],int n,int k) {
if(k<1 || k>n) {
cout<<"请输入正确的k!"< return 0;
}
return select(a,0,n-1,k);
}

int main() {
int a[100] ={0};
int m,k;
cout<<"请输入数组元素个数; ";
cin>>m;
cout<<"请输入需要查找第几个元素: ";
cin>>k;
srand(time(0));
cout<<"\n原数组为:"< for(int i=0; i a[i]=rand()%100;
cout< }
cout< cout<<"所给数组第"< return 0;
}

合集下载

第7章_随机化算法

第7章_随机化算法
4
随机化算法概述
一个随机化算法(randomized algorithm)是指 需要利用随机数发生器的算法,算法执行的某些 选择依赖于随机数发生器所产生的随机数。
5
随机化算法
随 机 化 算 法 有 时 也 称 概 率 算 法 ( probabilistic algorithm),但也有人对两者这样区分: 如果取得结果的途径是随机的,则称为随机算法,如拉斯维 加斯算法;而如果取得的解是否正确存在随机性,称为概率 算法,如蒙特卡罗算法。 本书中统一称为随机化算法。
24
蒙特卡罗(Monte Carlo)算法
•如果对于同一实例,蒙特卡罗算法不会给出2个不同的正确解答, 则称该蒙特卡罗算法是一致的。
•有些蒙特卡罗算法除了具有描述问题实例的输入参数外,还具 有描述错误解可接受概率的Байду номын сангаас数。这类算法的计算时间复杂性 通常由问题的实例规模以及错误解可接受概率的函数来描述。
17
舍伍德(Sherwood)算法
No.1
线性时间选择算法
No.2
快速排序算法
这两种算法的核心都在于选择合适的划分 基准。舍伍德算法随机地选择一个数组元素作 为划分基准。
18
舍伍德(Sherwood)算法
有时也会遇到这样的情况,即所给的确定性算法无法直接 改造成舍伍德型算法。
此时可借助于随机预处理技术,不改变原有的确定性算法, 仅对其输入进行随机洗牌,同样可收到舍伍德算法的效果。
27
主元素问题
设T[1:n]是一个含有n个元素的数组。当|{i|T[i]=x}|>n/2时, 称元素x是数组T的主元素。
template<class Type> bool Majority(Type *T, int n) {// 判定主元素的蒙特卡罗算法 int i=rnd.Random(n)+1; Type x=T[i];// 随机选择数组元素 int k=0; for (int j=1;j<=n;j++) if (T[j]==x) k++; return (k>n/2); // k>n/2 时T含有主元素 } template<class Type> bool MajorityMC(Type *T, int n, double e) {// 重复调用k次Majority算法 int k=ceil(log(1/e)/log(2)); for (int i=1;i<=k;i++) if (Majority(T,n)) return true; return false; }

计算机算法与设计复习题(含答案)

计算机算法与设计复习题(含答案)

1、一个算法的优劣可以用(时间复杂度)与(空间复杂度)与来衡量。

2、回溯法在问题的解空间中,按(深度优先方式)从根结点出发搜索解空间树。

3、直接或间接地调用自身的算法称为(递归算法)。

4、 记号在算法复杂性的表示法中表示(渐进确界或紧致界)。

5、在分治法中,使子问题规模大致相等的做法是出自一种(平衡(banlancing)子问题)的思想。

6、动态规划算法适用于解(具有某种最优性质)问题。

7、贪心算法做出的选择只是(在某种意义上的局部)最优选择。

8、最优子结构性质的含义是(问题的最优解包含其子问题的最优解)。

9、回溯法按(深度优先)策略从根结点出发搜索解空间树。

10、拉斯维加斯算法找到的解一定是(正确解)。

11、按照符号O的定义O(f)+O(g)等于O(max{f(n),g(n)})。

12、二分搜索技术是运用(分治)策略的典型例子。

13、动态规划算法中,通常不同子问题的个数随问题规模呈(多项式)级增长。

14、(最优子结构性质)和(子问题重叠性质)是采用动态规划算法的两个基本要素。

15、(最优子结构性质)和(贪心选择性质)是贪心算法的基本要素。

16、(选择能产生最优解的贪心准则)是设计贪心算法的核心问题。

17、分支限界法常以(广度优先)或(以最小耗费(最大效益)优先)的方式搜索问题的解空间树。

18、贪心选择性质是指所求问题的整体最优解可以通过一系列(局部最优)的选择,即贪心选择达到。

19、按照活结点表的组织方式的不同,分支限界法包括(队列式(FIFO)分支限界法)和(优先队列式分支限界法)两种形式。

20、如果对于同一实例,蒙特卡洛算法不会给出两个不同的正确解答,则称该蒙特卡洛算法是(一致的)。

21、哈夫曼编码可利用(贪心法)算法实现。

22概率算法有数值概率算法,蒙特卡罗(Monte Carlo)算法,拉斯维加斯(Las Vegas)算法和舍伍德(Sherwood)算法23以自顶向下的方式求解最优解的有(贪心算法)24、下列算法中通常以自顶向下的方式求解最优解的是(C)。

线性时间选择算法实现

线性时间选择算法实现
void swap(int *a,int *b);
//主函数
int main()
{
int *a,cnt,i,k,result;
FILE *fp;
//clrscr();
printf("Input the count of elements:");
scanf("%d",&cnt);
printf("Choose the element :");
{
int i=p,j=r+1;
while(1)
{
while(a[++i]<x&&i<r);
while(a[--j]>x);
if(i>=j)
break;
swap(&a[i],&a[j]);
}
a[p]=a[j];
a[j]=x;
return j;
}
void sort(int *a,int p,int r)
}
for(i=0;i<cnt;i++)
{
a[i]=rand()%cnt+100;
fprintf(fp,"%4d\n",a[i]);
}
result=select(a,0,cnt-1,k);
printf("The result is:%d",result);
fclose(fp);
free(a);
return 0;
if(k<=j) //比较k和j来确定在数组哪一部分继续选择
return select(a,p,i,k);
else

最坏情况线性时间的选择

最坏情况线性时间的选择

以期望线性时间做选择
2018/9/28
15
University of Science and Technology of China
第七讲 顺序统计学
内容提要:
最小值和最大值
以期望线性时间做选择
最坏情况线性时间的选择
2018/9/28
16
University of Science and Technology of China
2018/9/28 7
University of Science and Technology of China
最小值和最大值
如何设定当前最小值和最大值的初始值:依赖于n的奇偶性
如果n是奇数,将最小值和最大值都设为第一个元素的值; 如果n是偶数,就对前两个元素做一次比较,以决定最小值和最大值
选择问题:从一个由n个不同数值构成的集合中,选择其第i个顺 序统计量。
输入:一个包含n个(不同的)数的集合A和一个数i, 1≤ i ≤n 输出:元素 x A ,它恰大于A中其它i-1个元素。
2018/9/28 3
University of Science and Technology of China
MAX-MINIMUM ( A ) 1 if length[A] is odd 2 then min ← A[1]; max ← min; 3 else min ← MIN( A[1], A[2] ), max ← MAX( A[1], A[2] ); 4 i ++; 5 while i ≤ length[A] 6 min ← MIN( MIN(A[i], A[i+1]), min ) 7 max ← MAX( MAX(A[i], A[i+1]), max ) 8 i ← i+2; 9 end 10 return min, max

概率算法PPT课件

概率算法PPT课件

计算机语言提供的随机数发生器,一般会输出一个分布 在开区间(0, 1)上的随机小数,并且需要一个随机种子, 这个随机种子可以是系统当前的日期或时间。下面给出利用 C++语言中的随机函数rand产生的分布在任意区间[a, b]上的 随机数算法。
算法1——随机数发生器
int Random(int a, int b) { return rand( )%(b-a)+a; }
算法4——选择问题
int Select(int r[ ], int low, int high, int k)
{
if (high-low<=k) return r[high]; //数组长度小于k
else {
i=Random(low, high); //在区间[low, high]中随机选取一个元素
解。换言之,拉斯维加斯型概率算法找到正确解的 概率随着计算时间的增加而提高。
3.1 八皇后问题
八皇后问题是在8×8的棋盘上摆放八个皇后, 使其不能互相攻击,即任意两个皇后都不能处于同 一行、同一列或同一斜线上。
对于八皇后问题的任何一个解而言,每一个皇 后在棋盘上的位置无任何规律,不具有系统性,而 更像是随机放置的。由此想到拉斯维加斯型概率算 法:在棋盘上相继的各行中随机地放置皇后,并使 新放置的皇后与已放置的皇后互不攻击,直至八个 皇后均已相容地放置好,或下一个皇后没有可放置 的位置。
[ ri … rk … rs-1 ] rs [ rs+1 … … rj ] 均≤rs 轴值 均≥rs
查找这里 (a) 若k<s,则rk在轴值的前面
[ ri … … rs-1 ] rs [ rs+1 …rk … rj ] 均≤rs 轴值 均≥rs 查找这里 (b) 若k>s,则rk在轴值的后面

复杂度-线性时间选择算法复杂度分析

复杂度-线性时间选择算法复杂度分析

算法分析线性时间选择复杂度分析第二组:袁瑾(计科1304:201308010410),欧阳玉峰(计科1304:201308080216),程帆瑾(物联1302:201378010206)。

一、问题描述:给一个线性序列,要求在一个平均时间线性的情况下进行第k小元素的选择。

二、方法一:模仿快速排序的方法对输入序列进行递归划分,但只对划分出的子数组之一进行递归处理。

代码如下:RandomizedSelect(a, p, r, k):if p==r :return a[p]i = RandomizedPartition(a,p,r)j = i-p+1if k<=j :return RandomizedSelect(a,p,i,k)return RandomizedSelect(a,i+1,r,k-j)三、方法一时间复杂度:先从上边的函数说起。

其实质是模拟一个快速排序的过程。

快速排序是随机选择一个轴值,然后比轴值小的排在左边,比轴值大的排在右边。

上边的函数四个参数a,p,r,k。

a是数组的参数,p是数组开始元素的下标,r的数组结束的下标。

k是找第k小的元素。

每次划分所需要的时间是O(n),此时每个元素需要和轴值进行比较一次。

所以最好的情况是选完轴值一次快排后,左边刚好有k-1个元素,则此时轴值则是第k小元素。

而一般情况是,轴值左边有m个元素,m<k时,在右边找第k-m小的元素,m>k时,在左边找第k小的元素。

平均复杂度是O(n)。

最坏的情况是轴值每次选的都是刚好最大的元素或者最小的元素,此时时间复杂度是O(n*k)。

四.方法二:能在线性时间内找到一个划分基准,使得按照这个基准所划分出的两个子数组长度都至少为元数组长度的 m 倍:Select(a, p, r, k):if r-p<MG :sort(a[p:r])return a[p+k-1]for i in 0...(r-p-4)/5 :将a[p+5*i]...a[p+5*i+4]的第3小元素与a[p+i]交换x=Select(a,p,p+(r-p-4)/5,(r-p-4)/10)i=Partition(a,p,r,x)j=i-p+1if k<=j :return Select(a,p,i,k)return Select(a,i+1,r,k-j)五、算法及其复杂度分析:⌊3(n-5)/10⌋⌈n/5⌉<1> 将所有的数n个以每5个划分为一组共⌈n/5⌉组,将不足5个的那组忽略,然后用任意一种排序算法,因为只对5个数进行排序,所以任取一种排序法就可以了。

算法实验报告——线性时间选择问题

算法实验报告——线性时间选择问题实验五线性时间选择问题年级16 学号飞宇成绩专业信息安全实验地点C1-413 指导教师丽萍实验⽇期⼀、实验⽬的1、理解分治法的基本思想2、掌握分治法解决问题的基本步骤,并能进⾏分治算法时间空间复杂度分析。

⼆、实验容线性时间选择问题:给定线性序集中n个元素和⼀个整数k(k>=1⽽且k<=n),要求在线性时间找出这n个元素中第k⼩的元素。

1.随机快速排序2.利⽤中位数线性时间选择三、算法描述1.随机快速排序在算法Randomized_Select中执⾏Randomized_Partition,将数组分成两个⼦数组,在Randomized_Partition中调⽤Partition 函数确定⼀个基准元素,对数组进⾏划分。

由于划分是随机产⽣的,由此导致算法Randomized_Select也是⼀个随机化算法。

2.利⽤中位数线性时间选择四、程序1.随机快速排序#include#include#includeint Randomized_Select(int a[],int p,int r,int i);int Randomized_Partition(int a[],int p,int r);int Partition(int a[],int p,int r);void swap(int *a,int *b);int Random(int p,int q);int main(){int a[] = {10,9,8,7,6,5,4,3,2,1};int i = 3;printf("第%d⼩的数是:\n%d",i,Randomized_Select(a,0,9,i));return 0;}{int temp;temp = *a;*a = *b;*b = temp;}int Random(int p,int q)//产⽣p和q之间的⼀个随机整数{int i,number;srand((unsigned)time(NULL));number = rand()%(q-p+1)+p;return number;}int Partition(int a[],int p,int r)//快排的部分{int x = a[r];int i = p- 1;int j;for(j = p;j<=r-1;j++){if(a[j] <= x){i = i + 1;swap(&a[j],&a[i]);}}swap(&a[i+1],&a[r]);return i+1;}int Randomized_Partition(int a[],int p,int r)//随机交换数字{int i = Random(p,r);swap(&a[r],&a[i]);return Partition(a,p,r);int Randomized_Select(int a[],int p,int r,int i)//选择算法核⼼{if(p == r) return a[p];int q = Randomized_Partition(a,p,r);int k = q - p + 1;if(i == k)//如果刚好等于i,输出return a[q];else if(i < k)//如果i⽐k⼩,证明要找的元素在低区return Randomized_Select(a,p,q-1,i);else //找的元素在⾼区return Randomized_Select(a,q+1,r,i-k); //因为a[q]已经是前⾯第k个⼩的,所以在后⾯就是i-k⼩}2. 利⽤中位数线性时间选择#include#include#include#includeusing namespace std;templatevoid Swap(Type &x,Type &y);inline int Random(int x, int y);templatevoid BubbleSort(Type a[],int p,int r);templateint Partition(Type a[],int p,int r,Type x);templateType Select(Type a[],int p,int r,int k);int main(){//初始化数组int a[10];//必须放在循环体外⾯srand((unsigned)time(0));for(int i=0; i<10; i++)a[i] = Random(0,50);cout<<"a["<}cout<cout<<"第3⼩元素是"<//重新排序,对⽐结果BubbleSort(a,0,9);for(int i=0; i<10; i++){cout<<"a["<}cout<}templatevoid Swap(Type &x,Type &y){Type temp = x;x = y;y = temp;}inline int Random(int x, int y){int ran_num = rand() % (y - x) + x; return ran_num;}//冒泡排序templatevoid BubbleSort(Type a[],int p,int r) {//记录⼀次遍历中是否有元素的交换bool exchange;for(int i=p; i<=r-1;i++){exchange = false ;{if(a[j]{Swap(a[j],a[j-1]);exchange = true;}}//如果这次遍历没有元素的交换,那么排序结束if(false == exchange){break ;}}}templateint Partition(Type a[],int p,int r,Type x){int i = p-1,j = r + 1;while(true){while(a[++i]while(a[--j]>x);if(i>=j){break;}Swap(a[i],a[j]);}return j;}templateType Select(Type a[],int p,int r,int k){if(r-p<75)BubbleSort(a,p,r);return a[p+k-1];}//(r-p-4)/5相当于n-5for(int i=0; i<=(r-p-4)/5; i++){//将元素每5个分成⼀组,分别排序,并将该组中位数与a[p+i]交换位置//使所有中位数都排列在数组最左侧,以便进⼀步查找中位数的中位数BubbleSort(a,p+5*i,p+5*i+4);Swap(a[p+5*i+2],a[p+i]);}//找中位数的中位数Type x = Select(a,p,p+(r-p-4)/5,(r-p-4)/10);int i = Partition(a,p,r,x);int j = i-p+1;if(k<=j){return Select(a,p,i,k);}else{return Select(a,i+1,r,k-j);}}五、测试与分析1.随机快速排序O(n)2.利⽤中位数线性时间选择O(n)。

计算机算法与设计复习题(含答案)

计算机算法与设计复习题(含答案)1、一个算法的优劣可以用与与来衡量。

2、回溯法在问题的解空间中,按从根结点出发搜索解空间树。

3、直接或间接地调用自身的算法称为。

4、记号在算法复杂性的表示法中表示。

5、在分治法中,使子问题规模大致相等的做法是出自一种。

可以解决背包问题28、投点法是的一种。

29、若线性规划问题存在最优解,它一定不在30、n皇后问题可以用解决。

31、若L是一个NP完全问题,L经过多项式时间变换后得到问题l,则l是( P类问题 ).32、算法与程序在性质上有所不同,下列性质中,程序可以不满足哪个性质:。

案。

对;8)动态规划算法是用于解最优化问题,采用自顶向下的方式计算出最优解。

错;9)贪心算法和动态规划算法都要求问题必须具有最优子结构性质和贪心选择性质。

错; 10)队列式分支限界法将活结点表组织成一个优先队列,并按队列的先进现出原则选取下一个结点称为当前扩展结点。

错;四、算法设计说明:任意选择所使用的算法策略;要求:说问题)的思想。

6、动态规划算法适用于解问题。

7、贪心算法做出的选择只是最优选择。

8、最优子结构性质的含义是。

9、回溯法按策略从根结点出发搜索解空间树。

10、拉斯维加斯算法找到的解一定是。

11、按照符号O的定义O(f)+O(g)等于O(max{f(n),g(n)})。

12、二分搜索技术是运用策略的典型例子。

13、动态规划算法中,通常不同子问题的个数随问题规模呈级增长。

14、和是采用动态规划算法的两个基本要素。

15、和是贪心算法的基本要素。

16、是设计贪心算法的核心问题。

17、分支限界法常以或的方式搜索问题的解空间树。

18、贪心选择性质是指所求问题的整体最优解可以通过一系列的选择,即贪心选择达到。

19、按照活结点表的组织方式的不同,分支限界法包括和两种形式。

20、如果对于同一实例,蒙特卡洛算法不会给出两个不同的正确解答,则称该蒙特卡洛算法是。

21、哈夫曼编码可利用算法实现。

0046算法笔记——【随机化算法】舍伍德随机化思想解决跳跃表问题

问题描述如果用有序链表来表示一个含有n个元素的有序集S,则在最坏情况下,搜索S中一个元素需要O(n)计算时间。

提高有序链表效率的一个技巧是在有序链表的部分结点处增设附加指针以提高其搜索性能。

在增设附加指针的有序链表中搜索一个元素时,可借助于附加指针跳过链表中若干结点,加快搜索速度。

这种增加了向前附加指针的有序链表称为跳跃表。

应在跳跃表的哪些结点增加附加指针以及在该结点处应增加多少指针完全采用随机化方法来确定。

这使得跳跃表可在O(logn)平均时间内支持关于有序集的搜索、插入和删除等运算。

例如:如图,(a)是一个没有附加指针的有序表,而图(b)在图(a)的基础上增加了跳跃一个节点的附加指针。

图(c)在图(b)的基础上又增加了跳跃3个节点的附加指针。

在跳跃表中,如果一个节点有k+1个指针,则称此节点为一个k级节点。

以图(c)中跳跃表为例,看如何在改跳跃表中搜索元素8。

从该跳跃表的最高级,即第2级开始搜索。

利用2级指针发现元素8位于节点7和19之间。

此时在节点7处降至1级指针进行搜索,发现元素8位于节点7和13之间。

最后,在节点7降至0级指针进行搜索,发现元素8位于节点7和11之间,从而知道元素8不在搜索的集合S中。

相关原理在一般情况下,给定一个含有n个元素的有序链表,可以将它改造成一个完全跳跃表,使得每一个k级结点含有k+1个指针,分别跳过2^k-1,2^(k-1)-1,…,2^0-1个中间结点。

第i个k级结点安排在跳跃表的位置i2^k处,i>=0。

这样就可以在时间O(logn)内完成集合成员的搜索运算。

在一个完全跳跃表中,最高级的结点是级结点。

完全跳跃表与完全二叉搜索树的情形非常类似。

它虽然可以有效地支持成员搜索运算,但不适应于集合动态变化的情况。

集合元素的插入和删除运算会破坏完全跳跃表原有的平衡状态,影响后继元素搜索的效率。

为了在动态变化中维持跳跃表中附加指针的平衡性,必须使跳跃表中k级结点数维持在总结点数的一定比例范围内。

递归分治---例题5.线性时间选择

递归分治---例题5.线性时间选择⼀.问题描述给定线性序列集中的n个元素和正整数k, 1≤ k≤ n, 求第k⼩元素的位置.⼆.解题思路该篇⽂章中我们讨论与排序问题类似的元素选择问题,元素选择问题的⼀般提法是:给定线性序集合中n个元素和⼀个整数k(1 <= k <= n),要求找出这n个元素中第k⼩的元素,即如果将这n个元素依其线性排列数时,排在第k个位置的元素即为要找的元素.①最直观的解题⽅法:先排序,然后找到第k⼩的元素即可.这样时间复杂度⾄少是: O(n), 平均: O(nlogn)时间②随机选择算法:模仿快速排序对输⼊数组A进⾏⼆分划分,使⼦数组A1的元素<=A2中的元素,分点J由随机数产⽣,若K<=J,则K为A1的第K⼩元, 若K>J,则K为A2的第K-J⼩元.与快速排序算法不同,它只对⼦数组之⼀进⾏递归处理。

按照上⾯的思路,我们先⽤上篇⽂章说到过的随机选择算法来确定基准,从⽽对数组进⾏划分.代码描述:template<class T>int randomizedPartition(vector<T> &a, int p, int r) //在p:r中随机选择⼀个数i{srand(int(time(0))); //每次以当前时间作为随机数⽣成的种⼦int i = random(p, r);swap(a[i], a[p]); //将a[i]换到左端点return Partition(a, p, r);}Type RandomizedSelect(Type a[], int p, int r, int k){if(p == r) return a[p];int i = RandumizePartition(a, p, r); //使⽤了快速排序那篇⽂章中的RandomziedPartition随机划分算法j = i-p+1; //j为a[p:i]中的元素个数if(k <= j)return RandomizedSelect(a, p, i, k);elsereturn RandomizedSelect(a, i+1, r, k-j);}时间复杂度分析:若分点总是等分点,则有: Tmin(n) = dTmin(n) = T(n/2) + cn, 计算得到T(n) = θ(n)若⼀部分总是为空,则有: Tmax(n) = O(n^2)从上⾯可以看到,我们若果使⽤随机划分的话,最坏情况下,算法RandomizedSelect时间复杂度达到了O(n^2),例如,我们在找最⼩元素时,总是在最⼤元素处划分.尽管如此,该算法的性能还是可以的.随机选择算法的最佳情况即线性选择③线性时间选择算法(证明⽐较绕,可以直接记住结论:每次选择的基准为中位数的中位数,这样可以保证我们每次递归划分问题规模缩⼩1/4.当元素个数⼩于阈值的话,我们直接⽤sort排序)我们可以通过寻找⼀个好的划分基数,可使最坏情况下时间为O(n).下⾯我们来介绍⼀下如何划分可以达到⽬标,具体步骤如下:可以按以下步骤找到满⾜要求的划分基准,(「」表⽰向下取整,符号打不出来见谅.)将n个输⼊元素划分成「n/5」个组,每组5个元素,除可能有⼀个组不是5个元素外。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档