http://blog.sina.com.cn/s/blog_4ae8f77f0100uptr.html
主元素问题 算法设计与分析 时间复杂度nlogn和n
(2011-10-03 01:45:31) 一、主元素问题
1) 如果T中元素存在序关系,按分治策略设计并实现一个线性时间算法,确定T[0..n-1]是否有一个主元素。
2) 若T中元素不存在序关系,只能测试任意两个元素是否相等,试设计并实现一个O(nlogn)有效算法,确定T是否有一个主元素。进一步,能找到一个线性时间算法吗?
注:实现的算法要求列出足够的实验结果。
1)
中位数:数列排序后位于最中间的那个数。如果一个数列有主元素,那么必然是其中位数。求一个数列有没有主元素,只要看中位数是不是主元素。
找中位数的方法:选择一个元素作为划分起点,然后用快速排序的方法将小于它的移动到左边,大于它的移动到右边。这样就将元素划分为两个部分。此时,划分元素所在位置为k。如果k>n/2,那么继续用同样的方法在左边部分找;如果k<n/2就在右边部分找;k=n/2就找到了中位元素。
根据快速排序的思想,可以在平均时间复杂度为O(n)的时间内找出一个数列的中位数。然后再用O(n)的时间检查它是否是主元素。
对应的Java程序在MajorElement.java中
----------------------------------------------------------------------------------------
判断是否是主元素的伪代码:
master(A):
----------------------------------------------------------------------------------------
找一个序列中第k大的数伪代码
randomizedSelect(A , p , q , k):
----------------------------------------------------------------------------------------
实现随机划分的伪代码:
randomizedPartition(A , p , q ):
----------------------------------------------------------------------------------------
基于快速排序思想的划分伪代码:
partition(A , p , q ):
----------------------------------------------------------------------------------------
master()中求中位数可以在平均时间复杂度为O(n)的时间内完成,检查中位数是否是主元素耗时O(n),所以时间复杂度为O(n)。
2) 无序关系时求主元素的O(nlgn)的算法
<!--[if !supportLists]-->■
将元素划分为两部分,递归地检查两部分有无主元素。算法如下:
a. 若T 只含一个元素,则此元素就是主元素,返回此数。
d. 若m1 和m2 都存在且不等,则分别检查这两个数是否为T 的主元素,若有则返回此数,若无则返回空值。
e. 若m1 和m2 只有一个存在,则检查这个数是否为T 的主元素,若是则返回此数,若否就返回空值。
f. 若m1 和m2 都不存在,则T 无主元素,返回空值。
相应的Java程序在MasterElement.java中
-----------------------------------------------------------------------------------------
O(nlgn)的算法伪代码:
▹求T[p..q]中的主元素。返回主元素及其出现次数或空(表示无主元素)
CheckMaster(T , p , q):
then if a = b
-----------------------------------------------------------------------------------------
▹检查候选主元素是否是主元素
CheckAnotherPart(T , len , p , q , c , numc):
-----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
▹计算T[p..q]中element出现的次数
CheckNum( T , p , q , element):
----------------------------------------------------------------------------------------
<!--[if !supportLists]-->■
T(n)=2T(n/2)+n
所以时间复杂度为O(nlgn)
3)无序关系时求主元素的O(n)算法
在一个集合中,删除两个不同的数,则集合的主元素保持不变。根据这个原理,可以很快求出主元素。
-------------------------------------------------------------------------------------
相应的Java程序在MainElement.java中
master(A):
-------------------------------------------------------------------------------------
时间复杂度为O(n)