顺序统计算法设计-最大值和次最大值

题目描述

给定数组A[0…n-1],试设计一个算法,在最坏情况下用n+logn次比较找出A[0…n-1]中元素的最大值和次大值。

比较次数为2n的算法实现

	public static int[] findSecondFirst(int[] array) {
		int[] result=new int[2];
		int max=array[0]>array[1]?array[0]:array[1];
		int secondMax=array[0]>array[1]?array[1]:array[0];
		if(array[0]>array[1]) {
			max=array[0];
			secondMax=array[1];
		}else {
			max=array[1];
			secondMax=array[0];
		}
		for(int i=2;i<array.length;i++) {
			if(array[i]>max) {
				secondMax=max;
				max=array[i];
			}else if(array[i]>secondMax) {
				secondMax=array[i];
			}
		}
		result[0]=secondMax;
		result[1]=max;
		return result;
	}

比较次数为n+lgn的算法

算法思想

  1. 采用分治法将数组A[0:n]分成两部分,A[0:n/2-1]和A[n/2:n-1]
  2. 对于第一部分,i=0到n/2-1,如果A[i]>A[i+n/2],就交换A[i]和A[i+n/2]
  3. 数组A[n/2:n-1]的大小>2,则按照步骤2进行递归分治求出最大值和最小值;如果大小<=2,则直接求出最大值和次最大值。假设最大值为A[p],次最大值为A[p]
  4. 原问题的最大值为A[p],次最大值为A[p-n/2]和A[q]的较大者。

算法实现

	public static void search(int[] a,int[] result,int left,int right) {
		if(left==right) {
			result[0]=result[1]=left;
		}else if(left==right-1) {
			if(a[left]>a[right]) {
				result[1]=left;
				result[0]=right;
			}else {
				result[1]=right;
				result[0]=left;
			}
		}else {
			int m=(right-left+1)/2;
			for(int i=left;i<left+m;i++) {
				if(a[i]>a[i+m]) {
					int temp=a[i];
					a[i]=a[i+m];
					a[i+m]=temp;
				}
			}
			search(a,result,left+m,right);
			if(a[result[1]-m]>a[result[0]]) result[0]=result[1]-m;
		}
	}

测试结果

在这里插入图片描述

参考
百度文库-算法与设计

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 题目要求我们设计一个使用分治法思路,采用二分策略的算法,来求出一个含n个整数顺序存储的线性表的最大值和最小值。具体实现时,我们可以将线性表分成两个部分,分别求出左半部分的最大值和最小值,以及右半部分的最大值和最小值,然后将这四个值进行比较,得出整个线性表的最大值和最小值。 以下是具体的算法实现: 1. 定义一个函数,输入参数为线性表的起始位置和结束位置,输出参数为最大值和最小值。 2. 如果起始位置等于结束位置,说明线性表只有一个元素,直接返回该元素作为最大值和最小值。 3. 如果起始位置加1等于结束位置,说明线性表只有两个元素,比较这两个元素的大小,返回最大值和最小值。 4. 如果起始位置小于结束位置,将线性表分成两个部分,分别求出左半部分的最大值和最小值,以及右半部分的最大值和最小值。 5. 比较左半部分的最大值和右半部分的最大值,得出整个线性表的最大值。 6. 比较左半部分的最小值和右半部分的最小值,得出整个线性表的最小值。 7. 返回最大值和最小值。 以下是相应的测程序: #include <iostream> using namespace std; void findMinMax(int a[], int start, int end, int& minVal, int& maxVal) { if (start == end) { minVal = maxVal = a[start]; return; } if (start + 1 == end) { if (a[start] < a[end]) { minVal = a[start]; maxVal = a[end]; } else { minVal = a[end]; maxVal = a[start]; } return; } int mid = (start + end) / 2; int minVal1, maxVal1, minVal2, maxVal2; findMinMax(a, start, mid, minVal1, maxVal1); findMinMax(a, mid + 1, end, minVal2, maxVal2); minVal = min(minVal1, minVal2); maxVal = max(maxVal1, maxVal2); } int main() { int a[] = {3, 7, 1, 9, 2, 8, 5, 6}; int n = sizeof(a) / sizeof(int); int minVal, maxVal; findMinMax(a, , n - 1, minVal, maxVal); cout << "Min value: " << minVal << endl; cout << "Max value: " << maxVal << endl; return ; } ### 回答2: 分治法在解决问题时,采用将原问题分解成若干个子问题,逐个解决子问题再将子问题的最终解合并得到原问题的解。 对于给定的含n个整数顺序存储的线性表,采用二分策略可以先将整个序列分为两个子序列,分别求出各自的最大值和最小值,然后比较两个子序列的最大值和最小值,得到整个序列的最大值和最小值。 递归算法设计过程如下: 1. 定义求解最大值和最小值的函数,输入参数为线性表,起始下标和终止下标,输出最大值和最小值。 2. 如果起始下标等于终止下标,则最大值和最小值均为该元素。 3. 如果只有两个元素,比较得到最大值和最小值。 4. 如果有多于两个元素,则将线性表分成两段,分别求解两段的最大值和最小值。 5. 比较两段的最大值和最小值,得到整个序列的最大值和最小值。 测程序的编写如下: 1. 随机生成n个整数,存入线性表中。 2. 调用最大值和最小值函数,输出结果。 3. 对比程序输出结果和手动计算结果,检查程序的正确性。 下面是伪代码实现: 函数求最大值和最小值(List,start,end) 1. If (start = end) return (List[start], List[start]) 2. If (start + 1 = end) return (max(List[start], List[end]), min(List[start], List[end])) 3. middle <- (start + end) / 2 4. (max1, min1) <- 求最大值和最小值(List, start, middle) (max2, min2) <- 求最大值和最小值(List, middle+1, end) 5. return (max(max1, max2), min(min1, min2)) 主函数: 1. 生成n个随机整数 2. 调用函数求最大值和最小值,输出结果 3. 对比程序输出结果和手动计算结果 以上是如何采用分治法思路,基于二分策略设计求取线性表最大值和最小值的算法,以及相应测程序。 ### 回答3: 在给定一个含n个整数顺序存储的线性表的情况下,我们可以按照分治法的思路,采用二分策略,设计一个求出其最大值和最小值算法,并编写相应的测程序。该算法的时间复杂度为O(n)。 Step 1. 二分查找 我们可以通过二分查找来减少比较数,从而提高算法的效率。具体地,我们将线性表分成两部分,每选择一部分进行分析,通过不断缩小分析范围,最终得到所需的最大值和最小值。每选择一部分进行分析时,可以选择该部分的两个端点来进行比较,从而得出该部分的最大值和最小值。然后将剩余部分继续同样的操作。 Step 2. 递归求解 我们可以将该算法以递归的方式进行求解。具体地,我们可以将线性表划分为左半段和右半段,然后分别对左半段和右半段递归调用该算法,最终得到整个线性表的最大值和最小值。 Step 3. 测程序 测程序可以按照以下步骤进行编写: 1. 生成一个含有n个随机整数的顺序存储的线性表。 2. 调用求解最大值和最小值的递归算法,并输出结果。 3. 将结果与线性表中实际的最大值和最小值进行比较,检查算法的正确性。 4. 使用不同的n值进行测,观察算法的效率。 总结 通过分治法思路和二分策略,我们可以设计一个求解最大值和最小值的递归算法。该算法的时间复杂度为O(n),并且可以应用于大多数线性表实现方式,如顺序存储和链式存储。通过编写测程序并使用不同的数据进行测,可以检验算法的正确性和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值