求数组中的最大值和最小值

简介: 本文介绍了在程序中如何查找数组中的最大值和最小值,重点讲解了两种算法:普通算法和分治算法。普通算法通过遍历数组直接比较元素大小,找出最值;而分治算法则通过递归将数组划分成更小的部分,分别找出各部分的最大值,最终合并结果得到整个数组的最大值。文章以 {3,7,2,1} 为例,详细演示了两种算法的实现过程,并提供了 C、Java 和 Python 的代码示例。

程序中,我们经常使用数组(列表)存储给定的线性序列(例如 {1,2,3,4}),那么如何查找数组(序列)中的最大值或者最小值呢?


查找数组(序列)中最大值或最小值的算法有很多,接下来我们以 {3,7,2,1} 序列为例讲解两种查找最值的算法,一种是普通算法,另一种是借助分治算法解决。

普通算法

普通算法的解决思路是:创建两个变量 max 和 min 分别记录数组中的最大值和最小值,它们的初始值都是数组中的第一个数字。从第 2 个数字开始遍历数组,每遇到一个比 max 大的数字,就将它存储到 max 变量中;每遇到一个比 min 小的数字,就将它存储到 min 变量中。直到遍历完整个数组,max 记录的就是数组中的最大值,min 记录的就是数组中的最小值。


下面的动画,演示了找最大值的过程:


图1:数组中找最大值的过程

找最小值的过程和图 1 类似,这里不再给出具体的动画演示。

如下是普通算法对应的伪代码:

输入 num[1...n]              // 输入 n 个数字

max <- num[1]                // 将第 1 个数字赋值给 max(表示最大值)

min <- num[1]                // 将第 1 个数字赋值给 min(表示最小值)

for i <- 2 to n:             // 从第 2 个数字开始遍历

   if num[i] > max:         // 如果 max 小于遍历到的数字,则更新 max 的值

       max <- num[i]

   if num[i] < min:         // 如果 min 小于遍历到的数字,则更新 min 的值

       min <- num[i]

Print max , min              // 输出 max 和 min 的值

实现过程非常简单,感兴趣的读者可以自行编写对应的 C、Java 或者 Python 代码。

分治算法

下图展示了用分治算法查找 {3, 7, 2, 1} 中最大值的实现过程:


图2:分治算法找最大值


分治算法的实现思路是:不断地等分数组中的元素,直至各个分组中元素的个数 ≤2。由于每个分组内的元素最多有 2 个,很容易就可以找出其中的最值(最大值或最小值),然后这些最值再进行两两比较,最终找到的最值就是整个数组中的最值。


如图 2 所示,借助“分而治之”的思想,我们将“找 {3, 7, 2, 1} 中最值”的问题转换成了:先找出 {3 , 7]、[2 , 1} 中各自的最值,找出的最值再进行两两比较,最终就可以找到整个数组中的最值。


如下是分治算法求数组中最大值的伪代码:

输入 arr[1...n]           // 输入 n 个数字

arr_max(x , y) :          // 设计一个递归函数,[x , y] 用来限定查找最大数的范围

   if y-x ≤ 1 :         // 如果 y-x 的值小于等于 1,则比较 arr[x] 和 arr[y] 的值,大的就是最大值

       return max(arr[x] , arr[y])

   else :

       // 将 [x , y] 区域划分为 [x , ⌊(x+y)/2⌋ ] 和 [ ⌊(x+y)/2+1⌋ , y] 两个区域,求出两个区域内各自的最大值

       max1 = arr_max(x , ⌊(x+y)/2⌋ )    

       max2 = arr_max( ⌊(x+y)/2+1⌋ , y)

   return max(max1 , max2)   // 比较两个区域的最大值,最终找出 [x , y] 中的最大值


分治算法实现“求数组中最大值”的C语言程序如下:

  1. #include <stdio.h>
  2. //自定义函数,其中 [left,right] 表示 arr 数组中查找最大值的范围
  3. int get_max(int* arr, int left, int right) {
  4. int max_left = 0, max_right = 0, middle = 0;
  5. //如果数组不存在
  6. if (arr == NULL) {
  7. return  -1;
  8. }
  9. //如果查找范围中仅有一个数字
  10. if (right - left == 0) {
  11. return arr[left];
  12. }
  13. //如果查找范围中有 2 个数字,直接比较即可
  14. if (right - left <= 1) {
  15. if (arr[left] >= arr[right]) {
  16. return arr[left];
  17. }
  18. return  arr[right];
  19. }
  20. //等量划分成 2 个区域
  21.    middle = (right - left) / 2 + left;
  22. //得到左侧区域中的最大值
  23.    max_left = get_max(arr, left, middle);
  24. //得到右侧区域中的最大值
  25.    max_right = get_max(arr, middle + 1, right);
  26. //比较左、右两侧的最大值,找到 [left,right] 整个区域的最大值
  27. if (max_left >= max_right) {
  28. return  max_left;
  29. }
  30. else {
  31. return max_right;
  32. }
  33. }
  34. int main() {
  35. int arr[4] = { 3,7,2,1 };
  36. int max = get_max(arr, 0, 3);
  37. printf("最大值:%d", max);
  38. return 0;
  39. }


分治算法实现“求数组中最大值”的 Java 程序如下:

  1. public class Demo {
  2. public static int get_max(int [] arr,int left,int right) {
  3. //如果数组不存在或者数组内没有元素
  4. if (arr == null || arr.length == 0) {
  5. return -1;
  6. }
  7. //如果查找范围中仅有 2 个数字,则直接比较即可
  8. if(right - left <=1) {
  9. if(arr[left] >= arr[right]) {
  10. return arr[left];
  11. }
  12. return arr[right];
  13. }
  14. //等量划分成 2 个区域
  15. int middle = (right-left)/2 + left;
  16. int max_left = get_max(arr,left,middle);
  17. int max_right = get_max(arr,middle+1,right);
  18. if(max_left >= max_right) {
  19. return max_left;
  20. }else {
  21. return max_right;
  22. }
  23. }
  24. public static void main(String[] args) {
  25. int [] arr = new int[] { 3,7,2,1 };
  26. int max = get_max(arr,0,3);
  27.        System.out.println("最大值:"+max);
  28. }
  29. }


分治算法实现“求数组中最大值”的 Python 程序如下:

  1. def get_max(arr,left,right):
  2. #列表中没有数据
  3. if len(arr) == 0:
  4. return -1
  5. #如果查找范围中仅有 2 个数字,则直接比较即可
  6. if right - left <= 1:
  7. if arr[left] >= arr[right]:
  8. return arr[left]
  9. return arr[right]
  10. #等量划分成 2 个区域
  11.    middle = int((right-left)/2 + left)
  12.    max_left = get_max(arr,left,middle)
  13.    max_right = get_max(arr,middle+1,right)
  14. if max_left >= max_right:
  15. return max_left
  16. else:
  17. return max_right
  18. arr = [3,7,2,1]
  19. max = get_max(arr,0,3)
  20. print("最大值:",max,sep='')


以上程序的输出结果均为:

最大值:7

您可以根据伪代码和给出的找数组中最大值的程序,自行编写出找数组中最小值的程序,这里不再过多赘述。

相关文章
|
11月前
|
算法 Java C语言
弗洛伊德算法求最短路径
弗洛伊德算法用于寻找加权图中各顶点间的最短路径,适用于无向图和有向图。算法基于动态规划思想,通过枚举中间顶点来更新路径,确保最终得到最短路径。该算法要求路径权值非负,否则可能出错。
788 0
|
Linux 虚拟化
VMware虚拟机 用共享文件夹方式 与主机传输文件(图文)
VMware虚拟机 用共享文件夹方式 与主机传输文件(图文)
VMware虚拟机 用共享文件夹方式 与主机传输文件(图文)
|
11月前
|
设计模式 Linux 开发工具
Docker部署会吗?
本段内容主要介绍了Docker常用命令、Linux基础指令及日志查看方法,还涉及SpringMVC的执行流程、设计模式与注解,适合用于面试中技术能力的展示。
233 0
|
存储 数据库 索引
Python新手常见问题一:列表、元组、集合、字典区别是什么?
本文针对Python编程新手常遇到的问题,详细阐述了列表(List)、元组(Tuple)、集合(Set)和字典(Dictionary)这四种数据结构的核心区别。列表是一种有序且可变的数据序列,允许元素重复;元组同样有序但不可变,其内容一旦创建就不能修改;集合是无序、不重复的元素集,强调唯一性,主要用于数学意义上的集合操作;而字典则是键值对的映射容器,其中键必须唯一,而值可以任意,它提供了一种通过键查找对应值的有效方式。通过对这些基本概念和特性的对比讲解,旨在帮助初学者更好地理解并运用这些数据类型来解决实际编程问题。
4950 1
|
11月前
|
算法 Java C语言
汉诺塔问题
汉诺塔问题源自印度古老传说,涉及将一组圆盘从一根柱子移动到另一根,遵循特定规则。文章详细介绍了该问题的背景、解决思路以及如何使用分治算法实现,同时提供了C语言、Java和Python的代码示例。
750 0
|
11月前
|
算法
回溯算法的基本思想
本节介绍回溯算法,通过图1中从A到K的路径查找示例,说明其与穷举法的异同。回溯算法通过“回退”机制高效试探各种路径,适用于决策、优化和枚举问题。
371 0
|
11月前
|
算法 程序员
时间复杂度和空间复杂度的概念
本文介绍了如何评估算法的执行效率和内存占用,重点讲解了时间复杂度和空间复杂度的概念及其计算方法。通过大O记法,可以量化算法的运行时间和内存使用情况,从而在不同算法间做出合理选择。
427 0
|
11月前
|
算法 Java 定位技术
迷宫问题
迷宫问题是指在给定区域内寻找从起点到终点的可行路径。可以使用回溯算法解决,通过不断尝试四个方向(上下左右)移动,若无法前进则回退,直到找到终点或遍历所有可能路径。文中还给出了C语言、Java和Python的实现代码,并展示了运行结果。
401 0
|
缓存 安全 网络协议
HTTP和HTTPS的区别有哪些?
本文简要总结了 HTTP 和 HTTPS 的区别,从概念、端口、连接方式、使用场景、安全性等多个角度进行了对比。HTTP 是无状态的、无连接的应用层协议,适用于一般性网站和性能要求较高的应用;HTTPS 则通过 SSL/TLS 层提供加密、认证和完整性保护,适用于涉及敏感信息和高安全性的场景。文章还讨论了两者在性能上的差异,包括握手和加密开销、缓存效果以及 HTTP/2 的多路复用技术。最终,根据具体需求选择合适的协议能够更好地平衡安全性和性能。
18537 2
HTTP和HTTPS的区别有哪些?