【分治法】求数组的最大元和最小元

该博客探讨如何运用分治法在给定的n个数据元素中寻找最大元和最小元。虽然简单方法需要2n-3次比较,但通过分治法,可以降低比较次数,尽管时间复杂度仍为O(n)。文章提到更优的策略是将数组长度划分为2的幂次,以进一步减少比较次数。博主分享了算法的实现代码,并提供了makefile。
部署运行你感兴趣的模型镜像

给定n个数据元素,找出其中的最大元和最小元。

简单直观的方法:一个一个地找,用n-1次比较来找出最大元,再用n-2次比较找出最小元,比较次数(基本运算)为2n-3次。

此题最蛋疼的是为什么会想到用分治法来解决,为什么会知道分治法时间复杂度稍好,常数小?所以正常人不会往这方面想。


当用分治法时,时间复杂度的数量级不变,但比较次数减少,具体计算、证明参见邓建明老师算法课件。

本算法直接二分,更好地方法是将数组长度,划分为2的幂次,如n = 42,  42 = 32 + 8 + 2,这样比直接二分比较次数少一些,不过还是同一数量级O(n)。


1.h: 给main函数提供find_max_min的声明

#ifndef X1_H
#define X1_H

void find_max_min(const int *a, const int n, int &min, int &max);

#endif


1.cc:具体实现

#include <vector>
#include "1.h"
using std::vector;

static void find_max_min_core(const int *a, const int begin, const int end,
		vector<int> &vmin, vector<int> &vmax);

void find_max_min(const int *a, const int n, int &min, int &max)
{
	if (n < 0)
		return;
	if (n == 1)
	{
		min = max = a[0];
		return;
	}
	else
	{
		vector<int> vmin;
		vector<int> vmax;
		find_max_min_core(a, 0, n-1, vmin, vmax);

		vector<int>::iterator min_iter = vmin.begin();
		// 声明临时变量比直接用min引用效率高,因为引用需要间接
		// 访存,尤其在for循环中,效率更低
		int temp_min = *min_iter; 
		for (; min_iter != vmin.end(); ++min_iter)
		{
			if (temp_min > *min_iter)
				temp_min = *min_iter;
		}

		vector<int>::iterator max_iter = vmax.begin();
		int temp_max = *max_iter;
		for (; max_iter != vmax.end(); ++max_iter)
		{
			if (temp_max < *max_iter)
				temp_max = *max_iter;
		}

		min = temp_min;
		max = temp_max;
	}
}

static void find_max_min_core(const int *a, const int begin, const int end,
		vector<int> &vmin, vector<int> &vmax)
{
	if (begin > end)
		return;
	if (begin == end)
	{
		vmin.push_back(a[begin]);
		vmax.push_back(a[begin]);
		return;
	}
	else if (begin + 1 == end)
	{
		a[begin] < a[end] ?
			(vmin.push_back(a[begin]), vmax.push_back(a[end])) :
			(vmin.push_back(a[end]), vmax.push_back(a[begin]));
		return;
	}
	else
	{
		find_max_min_core(a, begin, begin + (end-begin)/2, vmin, vmax);
		find_max_min_core(a, begin + (end-begin)/2 +1, end, vmin, vmax);
	}
}

main.cc:

#include <iostream>
#include "1.h"

using std::cout;
using std::endl;
using std::cin;

static void input(int *a, int n);

int main()
{
	int num;
	cout << "Input the count of array: ";
	cin >> num;
	if (num <=0 )
		return 0;
	int *pa = new int[num];
	input(pa, num);
	
	int min = 0, max = 0;
	find_max_min(pa, num, min, max);

	cout << "min: " << min << endl;
	cout << "max: " << max << endl;

	delete[] pa;
	return 0;
}

static void input(int *a, int n)
{
	cout << "Input " << n << " numbers:" << endl;
	for (int i = 0; i < n; i++)
	{
		cin >> *(a+i);
	}
}

makefile:

main: main.o 1.o
	g++ -o main main.o 1.o
main.o: main.cc 1.h
1.o: 1.cc 1.h
clean:
	rm -f *.o main

运行结果:

xxl@xxl-pc:~/算法/分治法-求数组最大元和最小元$ ./main 
Input the count of array: 2
Input 2 numbers:
1 2
min: 1
max: 2
xxl@xxl-pc:~/算法/分治法-求数组最大元和最小元$ ./main 
Input the count of array: 1
Input 1 numbers:
4
min: 4
max: 4



您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值