`
十三月的
  • 浏览: 168823 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

分治策略(3篇)之标准分治

 
阅读更多

        第一篇:分治法之标准分治

目的:本篇博客并不具体的讨论某一个算法,而是将同类型的问题集中展示,从而对分治法有       更进一步的认识。

 

目录

  • 斐波那契数列问题
  • 台阶问题
  • 归并排序
  • 快速排序
  • BST镜像问题

问题1:斐波那契数列问题

       1)问题指出:

       斐波纳契数列,又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13……在数学上,斐波纳契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=F(n-1)+F(n-2)(n>=2,n∈N*)

       2)关键部分:

       当n>=2,求解Fn时,可以将该问题分解成 2个相同性质的子问题F(n-1)和F(n-2)。

       3)代码实现:

 

public static int Fibonacci(int n) {
		if (n == 0) {
			return 0;
		}
		if (n == 1) {
			return 1;
		}	

		return Fibonacci(n - 1) + Fibonacci(n - 2);
	}

  (上述代码并没有做输入参数值范围检查

问题2:台阶问题

1)问题指出:

 台阶问题是指:一个台阶总共有n级,一个人每次可以跳1级,也可以跳2级。求从最底层最高层总共有多少总跳法?

   2)关键部分

   设总跳法数目是:F(n)

   当台阶总数n = 1级时,F(n) = 1;

   当台阶总数n = 2级时,F(n) = 2;

   当台阶总数n >= 2级时,

   如果第一步跳1级,则剩下n-1级跳法总数是F(n-1);

   如果第一步跳2级,则剩下n-1级跳法总数是F(n-2);

   所以,结果是化成了2个相同性质规模更小的子问题F(n-1)和F(n-2)

         (问题转换成了问题1.)

 

 问题3:归并排序

       1)问题指出

       归并排序是指:对于一个待排序的数列,可以将该序列分成2个子数列,将这两个子数列分别排序,然后经2个已经排好序的子数列进行合并。

        2)关键部分:图片示意

                 
           

        3)代码实现:

 

public static void mergeSort(int[] data) {

		mergeSort(data, 0, data.length - 1);
	}

	private static void mergeSort(int[] data, int low, int high) {

		if (low < high) {
			int mid = (low + high) / 2;
			mergeSort(data, low, mid);
			mergeSort(data, mid + 1, high);
			merge(data, low, mid, high);
		}

	}

	// 合并
	public static void merge(int[] data, int start, int mid, int end) {
		int tmp[] = new int[end - start + 1];
		int i = start;
		int j = mid + 1;
		int k = 0;

		while (i <= mid && j <= end) {

			if (data[i] < data[j]) {
				tmp[k++] = data[i++];
			} else {
				tmp[k++] = data[j++];

			}
		}
		//拷贝左边数组的值
		while (i <= mid) {
			tmp[k] = data[i];
			k++;
			i++;
		}
		//拷贝右边数组的值
		while (j <= end) {
			tmp[k] = data[j];
			k++;
			j++;
		}

		// 重新赋值给data
		int m = 0;
		for (int n = start; n <= end; n++) {
			data[n] = tmp[m++];
		}

	}

 问题4:快速排序

     1)问题指出:

      快速排序是指:在一个待排序的序列中,指定一个分划值(比如第一个数值),运行一次分划函数使得该分划值排到序列某一位置,且该分划值左边的数值都小于等于分划值,右边的数值都大于等于该分划值。然后递归的对左边的序列使用快速排序,右边的序列使用快速排序。

      2)关键部分:图片示意

       3)代码实现

   

public static void  quickSort(int [] data,int start,int end){
		
		if(start >= end){
			return;
		}
		//分划
		int location = partition(data,start,end);
		//递归的排序
		quickSort(data,start,location-1);
		quickSort(data,location+1,end);
		
	}

    快速排序代码很是简练,尤为漂亮。

   

//分划函数
private static int partition(int [] data,int start,int end){
		
		int point =start;
		int key = data[start];
		for(int j = point+1;j<=end;j++){
			if(data[j] < key){
				point++;
				int tmp = data[j];
				data[j] = data[point];
				data[point] = tmp;
			}
		}
		//交换
		int tmp = data[start];
		data[start] = data[point];
		data[point] = tmp;
		
		
		return point;
	}

 问题5:二叉搜索树镜像问题

      1)问题指出:

       假设原始的二叉搜索树的左子树节点的值都小于根节点的值,右子树节点的值大于根节点的值,现在需要将该二叉搜索树结构换成左子树节点的值都大于根节点的值,右子树节点的值都小于根节点。

       这个很简单:改变根节点左右子树的指针,然后递归调用分别改变左右子树。

      2) 关键部分:图片示意
 

 

      3)代码实现

   

//节点结构
	class BSTNode{
		int value;
		BSTNode left;
		BSTNode right;
	}
	void reverse(BSTNode root){
		
		if(root == null){
			return;
		}
		//交换左右子节点
		BSTNode tmp;
		tmp = root.left;
		root.left = root.right;
		root.right = tmp;
		//递归调用
		reverse(root.left);
		reverse(root.right);	
	}

 
   总结:

    标准分治法,Divide-and-Conquer,一般分成三个步骤:

    步骤一:Divide ,根据某个条件将大问题分成两个规模更小同类型的问题

    步骤二:Comquer,递归调用

    步骤三:Combine,合并



 

 

 

   

 

 

 

 

 

 

 

    

 

      

  • 大小: 58.7 KB
  • 大小: 21.2 KB
  • 大小: 9.5 KB
  • 大小: 80.8 KB
8
2
分享到:
评论
4 楼 十三月的 2013-04-12  
finallygo 写道
十三月的 写道
finallygo 写道
在快速排序的代码里可以加一些优化,比如在将小的数都排到左边的那个算法里,可以加一个语句
if(j == point) {
    continue;
}

这样就可以减少一些交换

没有太明白你的意思?point指针和j指针分别指向了大于key和小于key的地方,是需要交换的。不知道代码加到那里?

加在partition方法第八行的后面

呵呵 是的 你的意思是如果像第2个数字就比第1个数字小,可以添加判断从而无需“自己和自己交换”...
3 楼 finallygo 2013-04-12  
十三月的 写道
finallygo 写道
在快速排序的代码里可以加一些优化,比如在将小的数都排到左边的那个算法里,可以加一个语句
if(j == point) {
    continue;
}

这样就可以减少一些交换

没有太明白你的意思?point指针和j指针分别指向了大于key和小于key的地方,是需要交换的。不知道代码加到那里?

加在partition方法第八行的后面
2 楼 十三月的 2013-04-12  
finallygo 写道
在快速排序的代码里可以加一些优化,比如在将小的数都排到左边的那个算法里,可以加一个语句
if(j == point) {
    continue;
}

这样就可以减少一些交换

没有太明白你的意思?point指针和j指针分别指向了大于key和小于key的地方,是需要交换的。不知道代码加到那里?
1 楼 finallygo 2013-04-12  
在快速排序的代码里可以加一些优化,比如在将小的数都排到左边的那个算法里,可以加一个语句
if(j == point) {
    continue;
}

这样就可以减少一些交换

相关推荐

    分治策略---归并排序

    ### 分治策略与归并排序 #### 一、分治策略概述 在计算机科学领域,分治(Divide and Conquer)是一种非常重要的算法设计思想。它的基本思想是将一个复杂的问题分解成两个或更多的相同或相似的子问题,直到最后子...

    概率分治机器学习

    概率分治是一种融合了概率论和分治策略的机器学习方法。分治策略是一种在计算机科学中常用的算法设计范式,它将一个复杂的问题分解成两个或多个较小的子问题,递归解决这些子问题,然后再合并这些子问题的解以得到...

    实验4分治算法设计技术的应用.doc

    三、分治策略的优点 使用分治策略可以减少比较的次数,例如,在上面的实例中,用分治策略比较的过程只需 10 次,而直接比较法需要 14 次。这表明,使用分治策略可以提高求解的问题的效率。 四、分治策略的特点 ...

    最近点对+Fibonacci两个分治

    在计算机科学领域,分治策略是一种重要的算法设计思想,它将一个大问题分解为若干个相同或相似的小问题,然后分别解决这些小问题,最后将它们的解组合起来得到原问题的解。在这个主题中,我们将深入探讨"最近点对...

    分治法求两个大整数相乘

    本篇将介绍如何通过分治法来实现两个大整数的乘法。 #### 二、分治法简介 分治法是一种将复杂问题分解成若干个相似但规模较小的子问题,并递归解决这些子问题,最终将子问题的解组合成原问题解的算法策略。其基本...

    Hanoi(分治法之汉诺塔)

    汉诺塔(Hanoi Tower)是一个经典的递归问题,它基于分治法策略来解决。在计算机科学中,分治法是一种重要的算法设计思想,它将一个大问题分解为若干个规模较小、相互独立且与原问题形式相同的子问题来求解。汉诺塔...

    大整数乘法分治算法实现

    为了解决这个问题,计算机科学家们发展出了高效的算法,其中一种便是基于分治策略的Karatsuba算法。 分治法是一种解决复杂问题的有效策略,它将一个大问题分解成若干个小问题,然后分别解决这些小问题,最后将结果...

    分治法旋转数组

    分治法是一种常见的算法设计策略,其核心思想是将一个复杂的问题分解成两个或更多的相同或相似的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。在计算机科学中,分治法被广泛应用于排序...

    使用分治法的插入排序

    分治法是计算机科学中解决问题的一种策略,它将大问题分解为若干个规模较小、相互独立、与原问题形式相同的子问题,然后递归地解决这些子问题,最后将子问题的解合并得到原问题的解。插入排序虽然没有直接采用分治法...

    Fibonacci序列 分治法——C语言代码

    这时,我们可以利用分治策略的"记忆化搜索"或"动态规划"来优化递归,避免重复计算。 以下是基于分治法的一种可能的Fibonacci序列生成思路: 1. **基础情况**:对于较小的Fibonacci数(例如前两个数0和1),我们...

    分治排序算法

    分治排序算法是一种高效且重要的排序方法,它基于分治策略的思想来实现数据的快速排序。本文将深入探讨分治排序算法的基本原理、实现过程以及其在实际应用中的优势。 #### 二、分治法概述 分治法(Divide and ...

    分治法大整数乘法——大整数类实现版

    综上所述,这个大整数类实现了大整数乘法,利用分治策略减少了计算的复杂性,提高了运算效率。通过重载运算符,用户可以像操作普通整数一样方便地操作大整数。这种实现方法对于需要处理大量大整数计算的场景,如密码...

    基础算法 第7章 分治算法(C++版)-2021.02.04.pdf

    分治算法不仅应用于简单的搜索问题,它同样适用于许多其他类型的计算问题,比如合并排序(Merge Sort)算法和快速排序(Quick Sort)算法,都是分治策略的典型应用。合并排序算法将数组分成两半,递归地对每一半进行...

    MFC实现递归分治中多项式相乘和快速排序

    在本文中,我们将深入探讨如何使用Microsoft Foundation Class (MFC) 框架在VC++6.0环境下实现两个核心的算法:递归分治策略下的多项式相乘和快速排序。这两个算法都是计算机科学中基础且重要的算法,广泛应用于各种...

    RE_分治1

    分治算法是一种重要的编程策略,它将...这些知识不仅涵盖了二分查找的基本原理,还展示了如何灵活运用分治策略来解决不同类型的数组和矩阵问题。理解并熟练掌握这些方法,对于提升编程能力和解决实际问题具有重要意义。

    分治法快速排序算法QuickSort

    总的来说,快速排序是一种非常重要的排序算法,它充分利用了分治法的优势,通过巧妙的分区策略和递归实现,使得在大多数情况下都能获得高效的表现。理解和掌握快速排序对于提升编程能力,特别是在处理数据处理和算法...

    算法分析与设计实验报告-分治法.docx

    【分治算法】是计算机科学中一种重要的算法思想,它将一个大...总结来说,本实验报告通过实例详细介绍了分治法在快速排序算法中的应用,包括算法的设计、分析以及具体的C++实现,展示了分治策略如何有效解决复杂问题。

    最近点对问题 分治法.cpp.rar

    文件名“最近对问题 分治法.cpp”表明代码是用C++编写的,并且采用了分治策略来解决最近点对问题。 下面,我们详细探讨如何使用分治法解决最近点对问题: 1. **分治法步骤**: - **分解**:将输入的点集分为两半...

    分治算法找最大最小值和k值[参照].pdf

    在这个问题中,我们将使用分治策略来解决问题。首先,我们将n个元素分成两组:A1={A[1],...,A[int(n/2)]}和A2={A[int(N/2)+1],...,A[N]},然后分别求这两组的最大值和最小值。最后,我们将这两组的最大值和最小值相...

Global site tag (gtag.js) - Google Analytics