iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java举例讲解分治算法思想
  • 182
分享到

Java举例讲解分治算法思想

2024-04-02 19:04:59 182人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录分治算法什么是分治算法分治算法的思想分治法四大基本特征分治法求解问题的三个基本步骤分治算法解决问题过程的伪代码关于分治算法的举例归并排序基本步骤快速排序二分搜索算法小结分治算法

分治算法

什么是分治算法

顾名思义就是分而治之,分治法可以用来解决各种问题,是一种将复杂难解的问题分割成规模和结构相同或者相似的子问题,通过对简单子问题的求解而达到对原问题的求解目的的算法设计方法,在求解一个复杂问题时可以将其分解成若干个子问题,子问题还可以进一步分解成更小的子子问题,直到解决的子问题是一些基本的问题,并且求解方法是已知的,可以直接求解为止。分而治之的策略不但能够使原本复杂的问题变得更加清晰,而且能够将问题的规模缩小而降低问题求解的难度。

分治算法的思想

对于一个规模较大的问题,可以将这个规模较大的问题分解为n个规模较小的相互独立且与原问题结构相同的子问题进行求解。首先通过递归来解决这些子问题,然后对子问题的解进行合并得到原问题的解,这中求解问题的思路就是分治法。

简单可以理解为

首先将原问题分解为若干个子问题

各子问题的结构基本相似,规模基本相当

递归使分治的工具

  • 递归调用:问题和子问题的分解
  • 递归约束:对子问题的解进行合并

分治法四大基本特征

  • 原问题的规模缩小到一定程度时可以很容易的被求解。
  • 原问题可以分解成若干个规模较小的同构子问题。这是使用分治法的前提,这个特征和递归的思想差不多,满足这个特征的问题通常称这个问题具有最优子结构性质。
  • 各问题的解可以合并为原问题的解
  • 原问题所分出的各个子问题之间是相互独立的,即子问题之间不包含公共的子问题,

分治法求解问题的三个基本步骤

  • 分解(递归调用):将原问题分解为若干个相互独立,规模较小且与原问题形式相同的一系列子问题。在使用分治算法时,最好使各子问题的规模大致相同。
  • 解决(对子问题求解):如果子问题的规模小到可以直接被解决则直接解决,否则需要递归求解各个子问题。
  • 合并(递归约束):将各个子问题的结果合并成原问题的解,有些问题的合并方法比较明显,有些问题的合并方法比较复杂,或者存在多种合并方案,有些问题的合并方案并不明显需要具体问题具体分析。

分治算法解决问题过程的伪代码

 divide-and-conquer(p)//阀值
 {
     if(|p|<n0)adhoc(p);//如果问题可以直接求解,就直接求解。|p|代表问题的规模
     divide p into amaller subinstances P1,P2,P3......Pk;//将原问题分解成k个规模较小的子问题,且这些子问题的规模相当结构相似
     for(i=1;i<=k;i++)
         yi=divide-and-conquer(p)//递归求解各个子问题Pi,若分解的子问题还可以分解成若干个子子问题,就再对子问题进行分解
         return merge(y1,y2,y3......yk)//将子问题的解合并成原问题的解
 }  

关于分治算法的举例

归并排序

归并排序算法是用分治策略实现对规模为n的记录序列进行排序的算法,基本思想是:待排序记录分成大小大致相同的两个或多个子集合,分别对子集合进行排序,最终将两个排序号的子集合合并成所要求的排序好的集合。

package 算法设计与分析;
 public class 归并排序 {
 //arr是存放原始元素的数组,left数组arr的最左边,left是数组的最右边,mid是划分的终点,数组tmp是一个临时数组,就是一个辅助存储空间
         public static void main(String[] args) {
             int[] arr = {49,38,65,97,76,13,27};
             int[] tmp = new int[arr.length];    //新建一个临时数组存放,相当于是一个辅助空间
             mergeSort(arr,0,arr.length-1,tmp);
             for(int i=0;i<arr.length;i++){
                 System.out.print(arr[i]+" ");
             }
         }
         public static void merge(int[] arr,int left,int mid,int right,int[] tmp){
             int i = 0;
             int j = left,k = mid+1;  //左边序列和右边序列起始索引
             while(j <= mid && k <= right){
                 if(arr[j] <= arr[k]){
                     tmp[i++] = arr[j++];
                 }else{
                     tmp[i++] = arr[k++];
                 }
             }
             //若左边序列还有剩余,则将其全部拷贝进tmp[]中
             while(j <= mid){
                 tmp[i++] = arr[j++];
             }
             while(k <= right){
                 tmp[i++] = arr[k++];
             }
             for(int t=0;t<i;t++){
                 arr[left+t] = tmp[t];
             }
         }
         public static void mergeSort(int[] arr,int left,int right,int[] tmp){
             if(left<right){
                 int mid = (left+right)/2;
                 mergeSort(arr,left,mid,tmp); //对左边序列进行归并排序
                 mergeSort(arr,mid+1,right,tmp);  //对右边序列进行归并排序
                 merge(arr,left,mid,right,tmp);    //合并两个有序序列,相当于用tmp覆盖原来的arr
             }
         }
     }

基本步骤

  • 划分中点mid;
  • 分别对左右子区间归并排序,归并的结果(是一个有序序列)存放在数组tmp中,tmp是一个临时数组,相当于一个辅助存储空间;
  • 用tmp去覆盖原来的数组arr。

快速排序

快速排序又称为交换排序,是冒泡排序的一种,在快速排序中,记录的比较和交换是从两端向中间进行的,关键字值较大的记录一次就能交换到后面单元,关键字值小的记录一次就能交换到前面单元,记录每次移动的距离较大,因而总的比较和移动次数较少。

思想:把最左边的元素作为主元,数组一左一右两个指针进行扫描,左边的指针直到找到一个元素比主元大时,便停止左移,右边的指针向左移动,直到找到一个不大于主元的元素,交换两个指针所指向的元素。

注意:这种排序要在左边设置一个较大的值作为哨兵,防止左指针在右移的过程中移出序列之外。

package 算法设计与分析;
 public class 快速排序 {
         public static void quickSort(int[] arr,int left,int right){
             int i,j,temp,t;
             if(left>right){
                 return;
             }
             i=left;
             j=right;
             //temp就是基准位,就是主元,将数组中的第一个元素作为主元
             temp = arr[left];
             while (i<j) {
                 //先看右边,依次往左递减
                 while (temp<=arr[j]&&i<j) {
                     j--;
                 }
                 //再看左边,依次往右递增
                 while (temp>=arr[i]&&i<j) {
                     i++;
                 }
                 //如果满足条件则交换
                 if (i<j) {
                     t = arr[j];
                     arr[j] = arr[i];
                     arr[i] = t;
                 }
             }
             //最后将基准为与i和j相等位置的数字交换
             arr[left] = arr[i];
             arr[i] = temp;
             //递归调用左半数组
             quickSort(arr, left, j-1);
             //递归调用右半数组
             quickSort(arr, j+1, right);
         }
         public static void main(String[] args){
             int[] arr = {72,26,57,88,42,80,72,48,60,};
             quickSort(arr, 0, arr.length-1);
             for (int i = 0; i < arr.length; i++) {
                 System.out.print(arr[i]+ " ");
             }
         }
     }

二分搜索算法

在一个表中搜索确定一个关键字值为给定的元素,若在表中存在这样的元素,则搜索成功,搜索结果可以返回整个数据的元素,也可以指示该元素在表中的位置,若表中不存在关键字值的元素,则搜索失败。

 package 算法设计与分析;
 //用递归的方法解决二分搜索问题
 public class 二分查找 {
     public static void main(String[] args) {
         int[] arr = {-7,-2,0,15,27,54,80,88,102};
         //想要查找的元素
         int key = 80;
         //对查找到的元素进行定位
         int position = Search(arr,key,0,arr.length - 1);
         if(position == -1){
             System.out.println("查找的是"+key+",序列中没有该数!");
         }else{
             System.out.println("查找的是"+key+",找到位置为:"+position);
         }
     }
     public static int Search(int[] arr,int key,int left,int right){
         if(key < arr[left] &&key > arr[right] &&left > right){
             return -1;
         }
         int middle = (left + right) / 2;            //初始中间位置
         if(arr[middle] > key){
             //比关键字大则关键字在左区域
             return Search(arr, key, left, middle - 1);
         }else if(arr[middle] < key){
             //比关键字小则关键字在右区域
             return Search(arr, key, middle + 1, right);
         }else {
             return middle;
         }
     }
 }

小结

以上就是针对分治算法的详细分析,分治算法在我们解决问题的过程中可以使我们的问题变得简单化,降低时间复杂度,利用分治法解决问题比较稳定。

到此这篇关于Java举例讲解分治算法思想的文章就介绍到这了,更多相关Java分治算法内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java举例讲解分治算法思想

本文链接: https://www.lsjlt.com/news/147722.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java举例讲解分治算法思想
    目录分治算法什么是分治算法分治算法的思想分治法四大基本特征分治法求解问题的三个基本步骤分治算法解决问题过程的伪代码关于分治算法的举例归并排序基本步骤快速排序二分搜索算法小结分治算法 ...
    99+
    2024-04-02
  • java分治思想之ForkJoin详解
    目录前言分治思想算法归并排序快速排序Fork/JoinForkJoinPool构造器工作窃取法使用前言   当我们面对需要同时执行多个任务的情况时,往往需要耗费大...
    99+
    2023-05-18
    java分治思想ForkJoin java ForkJoin
  • 基本算法思想:递归+分治+动态规划+贪
    作者:心叶时间:2018-05-01 19:28 本文对应github地址:https://github.com/yelloxing/... 以上实现了常见算法的java、c语言、javascrpt(或node.js)、python3和g...
    99+
    2023-01-31
    递归 算法 思想
  • 详解Java实现分治算法
    目录一、前言二、分治算法介绍三、分治算法经典问题3.1、二分搜索3.2、快速排序3.3、归并排序(逆序数)3.4、最大子序列和3.5、最近点对四、结语一、前言 在学习分治算法之前,问...
    99+
    2024-04-02
  • Java分治法与二分搜索算法实例分析
    本文实例讲述了Java分治法与二分搜索算法。分享给大家供大家参考,具体如下:1、分治法分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题相互独立且与原问题相同。递归的解这些子问题,然后将各子问题的解合并得到原问题的...
    99+
    2023-05-30
    java 分治法 二分搜索
  • Java详细讲解分治算法如何实现归并排序
    目录1.什么是分治算法分治法基本思想2.分治算法的体现——归并排序归并排序基本思想3.代码实现1.什么是分治算法 分治法 分治法,字面意思是“分而治之”,就是把一个复杂的1问题分成两...
    99+
    2024-04-02
  • Java算法设计与分析分治算法
    目录一、前言二、分治算法介绍三、分治算法经典问题3.1、二分搜索3.2、快速排序3.3、归并排序(逆序数)3.4、最大子序列和3.5、最近点对四、结语一、前言 在学习分治算法之前,问...
    99+
    2024-04-02
  • java简明例举讲解泛型
    目录什么是泛型泛型类与接口派生子类泛型通配符类型擦除什么是泛型        早期的Object类型可以接收任意的对象类型,但是在实际的使用中...
    99+
    2024-04-02
  • C++递归与分治算法原理示例详解
    目录1. 汉诺塔问题2. 全排列问题3. 利用递归与分治策略寻找最大值4. 归并排序5. 快速排序6. 棋盘覆盖问题1. 汉诺塔问题   递归算法,分为 3 步:...
    99+
    2024-04-02
  • Java基于分治法实现的快速排序算法示例
    本文实例讲述了Java基于分治法实现的快速排序算法。分享给大家供大家参考,具体如下:package cn.nwsuaf.quick;public class Quick { public static void swap(int[] ...
    99+
    2023-05-30
    java 分治法 快速排序
  • C语言算法举例分析
    这篇文章主要介绍“C语言算法举例分析”,在日常操作中,相信很多人在C语言算法举例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C语言算法举例分析”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!最近,我一...
    99+
    2023-06-17
  • Java实例讲解枚举enum的实现
    目录一.枚举介绍1.自定义枚举实现(1)示例(2)测试结果2.enum关键字实现枚举(1)示例(2)测试结果3.enum关键字注意事项(1)示例一.枚举介绍 1.枚举是一组常量的集合...
    99+
    2024-04-02
  • Java编程中的分治算法怎么用
    Java编程中的分治算法怎么用,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一...
    99+
    2024-04-02
  • Java基于分治算法实现的棋盘覆盖问题示例
    本文实例讲述了Java基于分治算法实现的棋盘覆盖问题。分享给大家供大家参考,具体如下:在一个2^k * 2^k个方格组成的棋盘中,有一个方格与其它的不同,若使用以下四种L型骨牌覆盖除这个特殊方格的其它方格,如何覆盖。四个L型骨牌如下图:棋盘...
    99+
    2023-05-30
    java 分治算法 棋盘覆盖
  • Java数据结构与算法实例讲解
    这篇文章主要讲解了“Java数据结构与算法实例讲解”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java数据结构与算法实例讲解”吧! 为什么需要树这种结构数组存储方式分析:优点:通...
    99+
    2023-06-15
  • C/C++举例讲解关键字的用法
    目录staticstatic修饰全局变量static修饰局部变量static修饰函数constBOOLbreakcontinuestatic static修饰全局变量 static修...
    99+
    2024-04-02
  • 例题详解Java dfs与记忆化搜索和分治递归算法的使用
    目录一、dfs(深度优先搜索)1.图的dfs2.树的dfs二、记忆化搜索1.普通递归:O(2^n)2.记忆化搜索: O(n)三、分治四、算法题1.dia和威严 示例2.小红...
    99+
    2024-04-02
  • Java之理解Redis回收算法LRU案例讲解
    如何通俗易懂的理解LRU算法? 1.LRU是什么? LRU全称Least Recently Used,也就是最近最少使用的意思,是一种内存管理算法,最早应用于Linux操作系统。 L...
    99+
    2024-04-02
  • Java使用动态规划算法思想解决背包问题
    目录动态规划算法动态规划算法的思想最优性原理动态规划算法的三大特点动态规划算法中的0/1背包问题动态规划算法的优点小结动态规划算法 动态规划算法的思想 动态规划算法处理的对象是多阶段...
    99+
    2024-04-02
  • C#实现分治算法求解股票问题
    目录分治策略是:可使用分治法求解的一些经典问题分治算法 - 最大子数组问题 (1)暴力求解(2)分治法分治法实现大数相乘 C#实现分治策略是: 对于一个规模为n的问题,若该...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作