西电算法设计大作业

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

算法设计大作业寻找多数元素

班级:021151

学号:02115037

姓名:隋伟哲

(1)问题提出:

令A[1,2,…n]是一个整数序列,A中的整数a如果在A中出现的次数多余⎣n/2⎦,那么a称为多数元素。例如在序列1,3,2,3,3,4,3中,3是多数元素,

因为在7个元素中它出现了四次。有几个方法可以解决这个问题。蛮力方法是把每个元素和其他各个元素比较,并且对每个元素计数,如果某个元素的计数大于

⎣n/2⎦,就可以断定它是多数元素,否则在序列中就没有多数元素。但这样比较

的次数是n(n-1)/2=Θ(错误!未找到引用源。),这种方法的代价太昂贵了。比较有效的算法是对这些元素进行排序,并且计算每个元素在序列中出现了

多少次。这在最坏情况下的代价是Θ(n 错误!未找到引用源。).因为在最坏情况下,排序这一步需要Ω(n 错误!未找到引用源。)。另外一种方法是寻找中间元素,就是第⎡n/2⎤元素,因为多数元素在排序的序列中一定是中间元素。可以扫描这个序列来测试中间元素是否是多数元素。由于中间元素可以在Θ(n)时间内找到,这个方法要花费Θ(n)时间。

有一个漂亮的求解方法,它比较的次数要少得多,我们用归纳法导出这个算法,这个算法的实质是基于下面的观察结论。

观察结论:在原序列中去除两个不同的元素后,原序列的多数元素在新序列中还是多数元素。

这个结论支持下述寻找多数元素候选者的过程。将计数器置1,并令c=A[1]。从A[2]开始逐个扫描元素,如果被扫描的元素和c相等。则计数器加1,否则计数器减1.如果所有的元素都扫描完并且计数器的值大于0,那么返回c作为多数元素的候选者。如果在c和A[j](1

A[j+1,…n]上的过程调用candidate过程。算法的伪代码描述如下。(2)算法

Input: An array A[1…n] of n elements;

Output: The majority element if it exists; otherwise none;

1. c←candidate(1);

2. count←0;

3. for j←1 to n

4. if A[j]=c then count←count+1;

5. end for;

6. if count>⎣n/2⎦ then return c;

7. else return none;

candidate(m)

1. j←m; c←A[m]; count←1;

2. while j0

3. j←j+1;

4. if A[j]=c then count←count+1;

5. else count←count-1;

6. end while;

7. if j=n then return c;

8. else return candidate(j+1);

(3)代码

//Majority.cpp

#include

using namespace std;

int Candidate(int *A, int n, int m);

int Majority(int *A, int n);

int main()

{

int n;

cout << "please input the number of the array: ";

cin >> n;

int *A;

A = (int *) malloc(n*sizeof(int) );

cout << "please input the array: ";

for (int i = 0; i < n; i++)

cin >> A[i];

if (Majority(A, n) != 'N')

cout << "the majority is: " << Majority(A, n);

else

cout << "the majority element do not exist! ";

free(A);

cin.get();

cin.get();

return 0;

}

int Majority(int *A, int n)

{

int c = Candidate(A, n, 0), count = 0;

for (int j = 0; j < n; j++)

if (A[j] == c)

count += 1;

if (count > n / 2)

return c;

else return'N';

}

int Candidate(int *A, int n, int m)

{

int j = m, c = A[m], count = 1;

while (j < n && count>0)

{

j += 1;

if (A[j] == c)

count += 1;

else count -= 1;

}

if (j == n)

return c;

else return Candidate(A, n, j + 1); }

(4)运行结果

(5)设计实例

首先输入数据的个数n=7,然后依次读入n个数(1,3,2,3,3,4,3)。

1)现在开始进入程序。由于数组元素的下标是从0开始的,所以调用c = Candidate(A, n, 0);从第0个元素开始统计。首先令c=A[0]=1,count=1,j=0然后j=j+1=1,A[1]=3,且3!=c,count=count-1=0,判断if条件后,返还Candidate(A, n, j + 1)。

2)进入第二次递归调用, c = Candidate(A, n, 2), c=A[2]=2,count=1,j=2然后j=j+1=3,A[3]=3,且3!=c,count=count-1=0, 判断if条件后,返还Candidate(A, n, j + 1)。

3)进入第三次递归调用,c= Candidate(A, n, 4),

c=A[4]=3,count=1,j=4然后j=j+1=5,A[5]=4,且4!=c,

count=count-1=0, 判断if条件后,返还Candidate(A, n, j + 1)。

4)进入第四次递归调

c=Candidate(A, n, 6),c=A[6]=3,count=1,j=6,经过运算,判定if

相关文档
最新文档