算法分析——分治策略

1 分治策略概念

分治法是讲一个复杂的问题分成两个或者更多的相同或者相似的问题,这些子问题相互独立或者形式相同,再把子问题分解成更小的子问题,一直这样循环下去,直到最后子问题可以简单的直接求解,原问题的解即子问题解得合并。

例1.1

给定一个顺序表,编写一个求出其最大值与最小值的分治算法。

分析:假设我们的数据按顺序的存放在一个整型数组中,如果数组大小为1,那么就可以直接给出结果,如果大小为2,那么比较一次就可以给出结果,如果求解问题数组长度大于2,我们就把问题规模缩小,直到缩小到问题可以解决为止,所以分治策略算法如下:

#include "pch.h"
#include 
using namespace std;
//s代表当前分治段的起始下标,e代表结束下标,meter代表数组地址,max,min分别代表存放最大值最小值的地址
void partionGet(int s, int e, int *meter, int *max, int *min)
{
	if (e - s <= 1)
	{
		if (meter[s] > meter[e])
		{
			if (meter[s] > *max)
				*max = meter[s];
			if (meter[e] < *min)
				*min = meter[e];
		}
		else
		{
			if (meter[e] > *max)
				*max = meter[e];
			if (meter[s] < *min)
				*min = meter[s];
		}
		return;
	}
	int i = s+(e-s) / 2;
	partionGet(s, i, meter, max, min);//在这里使用了二分法
	partionGet(i+1, e, meter, max, min);

}
int main()
{
	int max=0, min=0;
	int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
	partionGet(0, 9, arr, &max, &min);
	cout << max << " " << min << endl;
	return 0;
}

排序问题

例1.2

归并排序,简单来说,归并排序就是利用了分治策略,楼主专门写过一篇关于归并排序递归算法与非递归算法的实现,在这里就不在重复写了,请点击下连接。

https://mp.csdn.net/postedit/83180119

例1.3

快速排序是一种基于分治策略排序的一种算法。其基本思想是对于给定的待排序序列a[p:r],按照以下步骤进行:

(1)分解,一a[p]作为基准将数组a[p:r]划分成三段a[p:q-1],a[q]和a[q+1:r],使a[p:q-1]中任何一个元素都小于a[q],a[q+1:r]中任何一个元素都大于a[q].下标q在划分过程中确定。

(2)递归求解,通过递归调用快速排序算法对a[p:q-1]和a[q+1:r]进行排序。

(3)合并,对于a[p:q-1]和a[q+1:r]的排序是就地进行的,所以在a[p:q-1]和a[q+1:r]都已经排好序后,,不需要进行任何计算,a[p:r]已经排好序。

基于这个思想,可实现快速排序算法:

void quickSort(int arr[], int left, int right)
{//对arr数组进行快拍,按照非递减有序排列
	if (left < right)//如果元素序列长度小于一不处理
	{
		int pivotpos = Partition(arr, left, right, right - left + 1);//一趟划分
		quickSort(arr, left, pivotpos);//处理左侧序列
		quickSort(arr, pivotpos + 1, right);//处理右侧序列
	}

对于含有n个元素的数组arr[0:n],进行快速排序只要调用quickSort(arr,0,n)即可。

算法中Partition是以一个确定的基准元素arr[p]对子数组arr[p:r]进行划分。

int Partition(int arr[], int low, int high, int num)
{
	int i = low, j = high, pivot = arr[low];//基准元素
	while (i < j)
	{
		while (i < j&&arr[j] >= pivot)//反向扫描,找第一个比基准小的元素,移到左边
			j--;
		if (i < j)
		{
			arr[i] = arr[j];
			i++;
		}
		while (i < j&&arr[i] < pivot)//找比基准大的元素,移到右边
			i++;
		if (i < j)
		{
			arr[j] = arr[i];
			j--;
		}
	}
	arr[i] = pivot;//将基准元素就位
	return i;
}

未完。。。。

你可能感兴趣的:(数据结构,算法设计与分析)