首页 > 代码库 > 编程之美2.10 寻找数组中的最大值和最小值

编程之美2.10 寻找数组中的最大值和最小值

      这个问题其实很容易解决,就是循环遍历一遍数组,然后找到数组中存在的最大值和最小值就可以了,书中主要讨论的问题是比较次数较小的方法,不过,书中已经证明了,无论用什么方法最少的比较次数也就是循环遍历一遍的比较,结果是O(1.5N)的,所以,很容易的可以解决这个问题。

      第一种方法:

      函数声明:

void DutFindMaxAndMinInArray_1(int*, int, int&, int&);
      

      源代码如下:

/*基本的解法寻找最大值和最小值*/
bool _DutFindMaxAndMinInArray = false;
void DutFindMaxAndMinInArray_1(int* A, int size, int& _max, int& _min)
{
	if (!A || size <= 0)
	{
		_DutFindMaxAndMinInArray = true;
		_max = -1;
		_min = -1;

		return;
	}

	if (size == 1)
	{
		_max = A[0];
		_min = A[0];

		return;
	}

	if (A[0] >= A[1])
	{
		_max = A[0];
		_min = A[1];
	}
	else
	{
		_max = A[1];
		_min = A[0];
	}
	/*过一遍循环,一次进行比对即可*/
	for (int i = 2; i < size; ++i)
	{
		if (A[i] > _max)
		{
			_max = A[i];
		}
		else if (A[i] < _min)
		{
			_min = A[i];
		}
	}
}

      然后,我们可以利用分治的解法去解决这个问题,意思就是寻找数组的前一半中的最大值和最小值,寻找数组后一半的最大值和最小值,然后再利用分治把原问题分成更小的问题。

      函数声明:

void DutFindMaxAndMinInArray_2(int*, int, int&, int&);
void DutFindMaxAndMinInArray_2(int*, int, int, int&, int&);

      源代码如下:

/*分治的方法寻找最大值和最小值*/
void DutFindMaxAndMinInArray_2(int* a, int size, int& max, int& min)
{
	if (!a || size <= 0)
	{
		_DutFindMaxAndMinInArray = true;
		max = -1;
		min = -1;

		return;
	}

	DutFindMaxAndMinInArray_2(a, 0, size - 1, max, min);
}

void DutFindMaxAndMinInArray_2(int* a, int low, int high, int& max, int& min)
{
	if (high - low <= 1)
    {
        if (a[high] > a[low])
        {
            max = a[high];
            min = a[low];
            return;
        }
        else
        {
            max = a[low];
            min = a[high];
            return;
        }
    }

    int maxL, minL;
    int maxR, minR;

    /*分别在左半边和右半边寻找最大值和最小值,之后比对两边的最值就可以了*/
    DutFindMaxAndMinInArray_2(a, low, low + (high - low) / 2, maxL, minL);
    DutFindMaxAndMinInArray_2(a, low + (high - low) / 2 + 1, high, maxR, minR);

    if (maxL > maxR)
    {
        max = maxL;
    }
    else
    {
        max = maxR;
    }
    if (minL > minR)
    {
        min = minR;
    }
    else
    {
        min = minL;
    }
}


      接下来,我们来看下书中的扩展问题,即怎样寻找数组中的第二大值。

      其实这个问题也是可以利用前面的分治思想,即寻找数组前面的一半符合要求的数值,再寻找数组后面的一半符合要求的数值就可以了。

      函数声明:

/*2.10扩展 寻找第二大数值*/
void DutFindMaxAndSecondMax(int*, int, int&, int&);
void DutFindMaxAndSecondMax(int*, int, int, int&, int&);

      源代码如下:

/*分治的思想寻找最大值和第二大值*/
bool _DutFindMaxAndSecondMax= false;
void DutFindMaxAndSecondMax(int* a, int size, int& max, int& max2)
{
	if (!a || size <= 0)
	{
		_DutFindMaxAndSecondMax = true;
		max = -1;
		max2 = -1;

		return;
	}

	DutFindMaxAndSecondMax(a, 0, size - 1, max, max2);
}

void DutFindMaxAndSecondMax(int* a, int low, int high, int& max, int& max2)
{
	if (high - low <= 1)
    {
        if (a[high] > a[low])
        {
            max = a[high];
            max2 = a[low];
            return;
        }
        else
        {
            max = a[low];
            max2 = a[high];
            
            return;
        }
    }

    int maxL, maxL2;
    int maxR, maxR2;

	/*找到两边的最大值和次大值,按照比较顺序比较即可*/
    DutFindMaxAndSecondMax(a, low, low + (high - low) / 2, maxL, maxL2);
    DutFindMaxAndSecondMax(a, low + (high - low) / 2 + 1, high, maxR, maxR2);

    if (maxL > maxR)
    {
        max = maxL;
        if (maxL2 > maxR)
        {
            max2 = maxL2;
        }
        else
        {
            max2 = maxR;
        }
    }
    else
    {
        max = maxR;
        if (maxR2 > maxL)
        {
            max2 = maxR2;
        }
        else
        {
            max2 = maxL;
        }
    }
}



编程之美2.10 寻找数组中的最大值和最小值