分治法c语言求最大最小值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分治法c语言求最大最小值相关的知识,希望对你有一定的参考价值。

#include <stdio.h>
int min,max,min1,max1,min2,max2;
int a[10]=1,345,231,23,12,22,45,24,12,2;

int minmax( int *i,int *j,int max,int min)


if(i==j)

min=max=*i;

else if(i+1==j)


if(*i>*j)

min=*j;
max=*i;

else

min=*i;
max=*j;


else if((i+1!=j)&&(i!=j))

minmax(i,i+(j-i)/2,max1,min1);
printf("%d,%d\n",max2,min2);

minmax(i+(j-i)/2,j,max2,min2);
if(max1>max2)max=max1;
else max=max2;
if(min1>min2)min=min2;
else min=min1;




int main()


int minmax(int *i,int *j, int max,int min);
printf("%d,%d\n",a[0],a[9]);
minmax(a,a+9,max,min);
printf("%d,%d\n",max,min);

这个程序问题出在哪儿?谢谢!

1、分治法不是用来求最大值最小值的。在计算机科学中,分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序)。

分治法的精髓:

分--将问题分解为规模更小的子问题;

治--将这些规模更小的子问题逐个击破;

合--将已解决的子问题合并,最终得出“母”问题的解。


2、求数组中的最大值和最小值,一般使用假设法,即假设数组的第1个元素为最大值,同时也是最小值,然后遍历数组,找到最大值和最小值。示例如下:

#include<stdio.h>
int main() 
 
int a[] = 1,2,3,4,5,6,7,8,9,10;
int max, min;
max = min = a[0]; //假设第1个元素即是最大值也是最小值。
int max_pos = 0, min_pos = 0;
//遍历数组,找出数组a中的最大数和最小数
for (int inx=0; inx!=sizeof(a) / sizeof(int); ++inx) 
if (a[inx]> max) max = a[inx], max_pos=inx;
else if (a[inx] < min) min = a[inx], min_pos=inx;

printf("最大数:%d\\t最小数:%d\\n", max ,min );
return 0;

参考技术A 1)问题出在minmax函数,这个函数找到的最大值和最小值没有返回。
2)虽然你定义了最大值和最小值为全局变量,但是在minmax函数的调用参数中你又定义了同名变量,这样在minmax函数内部实际使用的是局部变量。
3)最简单的方法,直接把minmax函数的后两个输入参数去掉。本回答被提问者采纳

使用分治法是不是会提高在数组中查找最大值和最小值的时间复杂度

【中文标题】使用分治法是不是会提高在数组中查找最大值和最小值的时间复杂度【英文标题】:does using divide & conquer improve the time complexity to find max and min in an array使用分治法是否会提高在数组中查找最大值和最小值的时间复杂度 【发布时间】:2015-03-06 07:08:07 【问题描述】:

这是我在面试中被问到的问题。

找到数组的最小值和最大值的最佳时间复杂度是多少?

我回答:O(n)。遍历数组,跟踪到目前为止找到的最大值和最小值。非常简单直接。

面试官问你能不能用分而治之的方式来改进它。我说应该不会。然后谈话继续,最后我被要求实施分而治之的方法。

这里是:

public class MinMaxInArray 
    public static int[] findMinMax(int[] array, int i, int j)
        // base cases
        int arrLen = j - i + 1;
        if (arrLen == 1)
            return new int[]array[i], array[j];    //j and i are the same

        if (arrLen == 2)
            int min = Math.min(array[i], array[j]);
            int max = Math.max(array[i], array[j])           
            return new int[]min, max;
        

        // actual divide and conquer        
        int mid = i + (j-i)/2;
        int[] leftMinMax = findMinMax(array, i, mid);
        int[] rightMinMax = findMinMax(array, mid+1, j);
        return new int[]  Math.min(leftMinMax[0], rightMinMax[0]), Math.max(leftMinMax[1], rightMinMax[1])   ;
    

    public static void main(String[] args)
        int[] array = 20, 5, 7, 25, 30, 1, 9, 12;
        int[] minMax= findMinMax(array, 0, array.length - 1);           //minMax[0] = minimum value, minMax[1] = maximum value
        System.out.println("min = " + minMax[0] + ", max = " + minMax[1] );
    


我相信这仍然是 O(n),因为所有元素都进行了比较。但是面试官坚持说是O(log n),让我考虑一下。我想了很多,我确信它是 O(n)。如果我是正确的,仅仅应用分而治之并不总能降低复杂性。

如果我理解这个算法仍然是 O(n),请纠正我。

谢谢

【问题讨论】:

问题本身(迭代/划分&征服)和标题(二分查找)之间有什么联系? 【参考方案1】:

你是对的。除非对数组进行排序,否则您仍然必须检查每一半的每个元素(以及重复出现的每季度和每八分之一)。

它可以是 O(log N) 的唯一方法是如果您可以丢弃每个递归级别的一半搜索空间(例如在排序列表中搜索特定值)和 only 方法如果已排序,则可能发生这种情况。

但是,当然,minmax 操作变成了 O(1),因为您只需获取列表的第一个和最后一个元素,根本不需要搜索。

现在可能考官建议分而治之,将每个问题级别的不同部分分配给不同的执行引擎,以便它们可以并行运行。这是我能看到它给你 O(log N) 的唯一另一种方式,但我没有看到基于发布的内容表明情况如此的真实证据,我认为它需要相当多的引擎。

【讨论】:

考官可能还一直在考虑无法容纳在内存中的非常大的数据数组(例如在有限的内存设备上),那么分而治之可能有助于避免过多的磁盘交换。 【参考方案2】:

确实,使用分治法求最小值和最大值的时间复杂度是 O(n)。

但是使用分治法可以在很大程度上减少比较次数,如果数据量很大,确实可以减少时间。

因此,如果 n 是 2 的幂,分治法进行 3/2n -2 次比较。如果 n 不是 2 的幂,则它进行超过 3/2n -2 次比较。

【讨论】:

【参考方案3】:

我也同意“使用分治求最小值、最大值”是 O(N) 因为在《分而治之》 Divide ---> 花费 O(n),因为它将每个片段分成更小的片段。 征服--->它可以是任何函数,它会给出结果。所以时间复杂度将基于征服正在做什么。与合并排序一样,合并部分需要 log(n) 时间。

在这种情况下,征服是不断的操作

【讨论】:

以上是关于分治法c语言求最大最小值的主要内容,如果未能解决你的问题,请参考以下文章

基础算法 分治法求最大最小元

分治法求一个数组中最大最小值

HNUCM-1435 最大最小值(分治法)

分治法 解决最大字段和问题

分治法解决寻找数组中最大最小值的问题

使用分治法是不是会提高在数组中查找最大值和最小值的时间复杂度