算法导论9-2

读书笔记

本小节介绍一种选择算法,用来选择数组中第\(i\)小的元素;

\(RANDOMIZED-SELECT\)以快速排序为模型,时间复杂度为\(\theta(n)\)

伪代码如下:

RANDOMIZED-SELECT(A, p, r, i)
if p == r
	return A[p]
q = RANDOMIZED-PARTITION(A, p, r)
k = q - p + 1
if i == k
	return A[q]
else if i < k
	return RANDOMIZED-SELECT(A, p, q - 1, i)
else return RANDOMIZED-SELECT(A, q + 1, r, i - k)

关于\(RANDOMIZED-PARTITION\)请查阅第七章快速排序的内容,这个函数的作用是根据随机数对给定范围的数组分区,比随机数大的在右边,比随机数小的在左边。

对伪代码的解读:

  1. 如果指定范围内的数组只有一个元素,则返回这一元素。
  2. 然后通过\(RANDOMIZED-PARTITION\),获取随机数在数组中的次序。
  3. 对比这一次序,符合则返回这一元素。
  4. 然后根据次序和\(i\)的比较,递归执行左枝或者右枝;

对时间复杂度的分析过程看的头疼,略。

课后习题

9.2-1

证明:在\(RANDOMIZED-SELECT\)中对长度为\(0\)的数组,不会进行递归调用。

答案显而易见,空集不会调用函数。

9.2-2

请讨论:指示随机变量\(X_k\)\(T(max(k-1,n-k))\)是独立的。

9.2-3

给出\(RANDOMIZED-SELECT\)的一个基于循环的版本。

public int randomnized_select_loop(int[] a, int start, int end, int i) throws Exception{
		if(i > a.length || i <= 0)
			throw new Exception("Invalid i!");
		
		if(a.length == 1)
			return a[0];
		
		int mid = qs.partition_Randomized(a, start, end);
		while(mid + 1 != i){
			if(mid + 1 < i)	//search right
				mid = qs.partition_Randomized(a, mid + 1, end);
			else	//search left
				mid = qs.partition_Randomized(a, start, mid - 1);
		}
		return a[mid];
	}

9.2-4

假设用\(RANDOMIZED-SELECT\)去选择数组\(A=<3,2, 9, 0, 7,5,4,8,6,1>\)的最小元素,给出能够导致\(RANDOM-SELECT\)最坏情况发生的一个划分序列。

也就是快速排序中最不平衡的情况,\(<0,1,2,3,4,5,6,7,8,9>\)

posted @ 2021-01-15 11:09  ijkzen  阅读(233)  评论(0编辑  收藏  举报