算法分析及实例解析(一)——分治法

分治法(divide and conquer)

对于一个规模为n的问题,若该问题可以容易地解决,则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立,且与原问题形式相同,递归地解决这些子问题,然后将各子问题的解合并,得到原问题的解。这种算法设计策略叫做分治策略。

分治法在每层递归上由三个步骤组成:

  • 1)划分(divide):将原问题分解成若干规模较小、相互独立、与原问题形式相同的子问题。
  • 2)解决(conquer):若子问题规模较小,则直接求解,否则递归求解各子问题。
  • 3)合并(combine):将各子问题合并为原问题的解。
分治法有哪些经典例子呢?那可就多了,比较常见的将在下面一一列出分析。

二分法查找

二分法解决的基本问题是,在已知的n个已序数列中,查找给定元素是否存在。二分法的基本思想用到了二叉查找树的结构。

下面我们给出其c++程序代码:
#include 
#include 
#include 
#include 
#include 
 
int * rand_seq(int num)//产生num个随机序列
{
	int *tem=new int[num]; 
	srand((unsigned)time(NULL));
	for(int i=0;i(std::cout," "));
	std::cout<

找最大值与最小值

问题描述:在n个不同元素的集合中,同时找出它的最大值和最小值。

采用普通的遍历法,最坏情况比较次数为2(n-1),分治法比较次数为3n/2-2,且看代码:
#include 
#include 
#include 
#include 
#include 
#include 
 
int * rand_seq(int num)//产生num个随机序列
{
	int *tem=new int[num]; 
	srand((unsigned)time(NULL));
	for(int i=0;i(std::cout," "));
	std::cout<*end)?(res_max=*begin,res_min=*end):
					  (res_max=*end,res_min=*begin);
	}else
	{
		int *mid=begin+(end-begin)/2;
		int lmax=INT_MIN,rmax=INT_MIN,lmin=INT_MAX,rmin=INT_MAX;
		rec_MaxMin(begin,mid,lmax,lmin);
		rec_MaxMin(mid+1,end,rmax,rmin);
		res_max=std::max(lmax,rmax);
		res_min=std::min(lmin,rmin);
	}
} 

int main(int argc, char** argv) 
{
	int *data=rand_seq(20);
	print_seq(data,20);
	//先赋初值,INT_MAX和INT_MIN在limits.h中定义 
	int max=INT_MIN;
	int min=INT_MAX;
/*	std::cout<  
  

求第k小元素问题

这个问题是由求最大值最小值问题引申出来的,问题描述:在n个不同元素的集合中,找出它的第k小值。该问题又叫选择问题。

当1

如果采用快速排序中的分划方法,以主元为基准,将一个表划分成左右两个子表。设原表长为n,假定经过一趟分划,分成两个左右子表,其中左子表是主元及其左边元素的子表,设其长度为p,右子表为主元右边元素的子表。那么如果k==p,则主元就是第k小元素;若k

下面上两种思路的代码:

#include 
#include 
#include 
#include 
#include 
 
int * rand_seq(int num)//产生num个随机序列
{
	int *tem=new int[num]; 
	srand((unsigned)time(NULL));
	for(int i=0;i(std::cout," "));
	std::cout<data[left])?((rightdata[right])?right:left):((rightdata[right])?right:key);
		if(min_index!=key)
		{
			std::swap(data[key],data[min_index]);
			adjust_heap(data,min_index,num);
		}	
	}
}
void build_heap(int *data,int num)
{
	int max_index=(num-1)/2;
	for(int i=max_index;i>=0;i--)
		adjust_heap(data,i,num);
}

int k_min_heap(int *data,int num,int k)
{
	build_heap(data,num);
	for(int i=1;item) --right;
			while((left

归并排序&快速排序

这两种排序方法,都是利用分治排序的经典例子,尤其是归并排序:分解、排序、合并。

关于这两种方法的详细介绍,参考我的另一篇博文《排序总结:堆排序、快速排序、归并排序、基数排序

你可能感兴趣的:(数据结构与算法)