《算法导论》第九章----中位数和顺序统计学
2013-10-11 22:03
246 查看
《算法导论》学习记录目录
本章主要讲了如何在一个集合里找出第i个顺序统计量(即第i个小的元素),可以定义选择问题(n个元素中的第i个小的元素,即在n个元素里找出一个元素,这个元素大于其他i-1个元素)。
如果我们用堆排序或合并排序(Ο(nlgn))对该集合进行排序,然后直接找出第i个元素即可。这样一来,选择问题运行时间为Ο(nlgn)。但是本章讲其他两种方法可以使的选择问题的运行时间为O(n),分别为以期望线性时间做选择和最坏情况线性时间的选择。(PS:本人能力不足,对于最坏情况线性时间的选择的算法还在看,不能将其实现。。。。所以下文不会出现。。。)
最小值最大值
最小值和最大值都可以通过n-1次比较找出,先假设最小值(最大值)为第一个元素,再与剩下的元素比较,在比较过程中找出最小值(最大值)。
randomized_select
这个算法看起来会递归调用含有0个元素的子数组,但是这种情况不会发生。(长度为0的数组,会直接返回,不会递归调用)
这个算法的最坏情况运行时间为Θ(n2),即每次划分都是按余下的元素中最大的进行划分。但是该算法的平均情况性能较好,而且是随机化,故没有哪一种特殊的输入会导致最坏情况的发生。
具体关于期望的计算请见算导原文。。。。(有很多的计算和证明还在看。。。。)
虽然本章的页数很少,但是有很多习题和思考题。。。。以后一定要好好做了,并把最坏情况线性时间的选择也补上。。。。
继续努力!!!
本章主要讲了如何在一个集合里找出第i个顺序统计量(即第i个小的元素),可以定义选择问题(n个元素中的第i个小的元素,即在n个元素里找出一个元素,这个元素大于其他i-1个元素)。
如果我们用堆排序或合并排序(Ο(nlgn))对该集合进行排序,然后直接找出第i个元素即可。这样一来,选择问题运行时间为Ο(nlgn)。但是本章讲其他两种方法可以使的选择问题的运行时间为O(n),分别为以期望线性时间做选择和最坏情况线性时间的选择。(PS:本人能力不足,对于最坏情况线性时间的选择的算法还在看,不能将其实现。。。。所以下文不会出现。。。)
最小值最大值
最小值和最大值都可以通过n-1次比较找出,先假设最小值(最大值)为第一个元素,再与剩下的元素比较,在比较过程中找出最小值(最大值)。
#include <stdio.h> #include <stdlib.h> int randomized_partition(int A[], int p, int r); int partition(int A[], int p, int r); int randomized_select(int A[], int p, int r, int i); int randomized_select_iteration(int A[], int p, int r, int i); int main(){ int number; scanf("%d", &number); int *array = malloc(number * sizeof(int)); int i; for(i = 0; i < number; i++) scanf("%d", &array[i]); int which; scanf("%d", &which); //int select = randomized_select(array, 0, number-1, which); int select = randomized_select_iteration(array, 0, number-1, which); printf("%d\n", select); return 0; } int randomized_partition(int A[], int p, int r){ int i = p + rand() % (r - p + 1); int temp = A[i]; A[i] = A[r]; A[r] = temp; return partition(A, p, r); } 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++; int temp = A[i]; A[i] = A[j]; A[j] = temp; } } int temp = A[i+1]; A[i+1] = A[r]; A[r] = temp; return i+1; } /* * 在数组下标为p到r中找出第i小的元素 */ int randomized_select(int A[], int p, int r, int i){ if(p == r) return A[p]; int q = randomized_partition(A, p, r); //在下标为p到r中随机找一个元素,以该元素为主元素划分数组,并返回该元素的位置 int k = q - p + 1; //主元素在数组下标为p到r中里为第几小的元素 if(i == k) //如果i等于k,主元素为要找的值 return A[q]; else if(i < k) //如果i小于k,说明要找的第i小的元素比主元素要小,所以只出现在主元素的左边的子数组里,而这时,第i小的元素在左边子数组依然为第i小。 return randomized_select(A, p, q-1, i); else //如果i大于,说明要找的第i小元素比主元素要大,所以只出现在主元素的右边的子数组里,而这时,第i小的元素在右边子数组应该为i-k小。子数组的位置为q+1,而q位置的元素为第k小的元素。 return randomized_select(A, q+1, r, i-k); } /* * 下面为迭代实现 */ int randomized_select_iteration(int A[], int p, int r, int i){ if(p == r) return A[p]; while(1){ int q = randomized_partition(A, p, r); int k = q - p + 1; if(i == k) return A[q]; else if(i < k){ r = q - 1; } else{ p = q + 1; i = i - k; } } }
randomized_select
这个算法看起来会递归调用含有0个元素的子数组,但是这种情况不会发生。(长度为0的数组,会直接返回,不会递归调用)
这个算法的最坏情况运行时间为Θ(n2),即每次划分都是按余下的元素中最大的进行划分。但是该算法的平均情况性能较好,而且是随机化,故没有哪一种特殊的输入会导致最坏情况的发生。
具体关于期望的计算请见算导原文。。。。(有很多的计算和证明还在看。。。。)
虽然本章的页数很少,但是有很多习题和思考题。。。。以后一定要好好做了,并把最坏情况线性时间的选择也补上。。。。
继续努力!!!
相关文章推荐
- 算法导论第九章:中位数和顺序统计学
- 《算法导论》学习总结 — 9.第九章 中位数和顺序统计学
- 算法导论第九章中位数和顺序统计学例题
- 《算法导论》学习总结 — 9.第九章 中位数和顺序统计学
- 算法导论 第9章 中位数和顺序统计学(线性时间选择算法)
- 算法导论——lec 09 中位数和顺序统计学
- 算法导论学习笔记——第9章 中位数和顺序统计学
- 《算法导论》读书笔记之第9章 中位数和顺序统计学
- 算法导论学习笔记-第九章-中位数和顺序统计学
- 算法导论-------------中位数和顺序统计学
- 《算法导论》读书笔记之第9章 中位数和顺序统计学 最坏情况是线性时间的选择算法
- 算法导论代码 第9章 中位数和顺序统计学
- 《算法导论》读书笔记之第9章 中位数和顺序统计学
- 第九章中位数和顺序统计学之“寻找第2小元素”(练习9.1-1待改进)
- 第九章中位数和顺序统计学之“查找第i小的元素(递归版)平均运行时间为O(n)算法”
- 第九章中位数和顺序统计学之“查找第i小的元素(迭代版)平均运行时间为O(n)算法”(练习9.2-3)
- 《算法导论》10、中位数和顺序统计学(C++)
- 《算法导论》学习总结——第二部分6中位数和顺序统计学
- 算法导论(第9章-中位数和顺序统计学)最大值和最小值
- 《算法导论》— Chapter 9 中位数和顺序统计学