热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java编写分治策略算法

**分治策略运用练习**一、实验目的本次实验是针对分治策略运用的算法设计及应用练习,旨在加深学生对该部分知识点的理解,提高学生运用该部分知识解决问题的能力。二、实验项目1.对用户输

**分治策略运用练习**

一、实验目的
本次实验是针对分治策略运用的算法设计及应用练习,旨在加深学生对该部分知识点的理解,提高学生运用该部分知识解决问题的能力。

二、 实验项目
1.对用户输入的杂乱无序的数字序列按照由小到大的顺序排序。要求分别运用合并排序和快速排序完成该题目要求。
2.棋盘覆盖问题。(要求N可由用户输入)

三、实验过程
(一)题目一:数字排序



  1. 题目分析
    用合并排序和快速排序的方法使得杂乱无序的数字序列按照由小到大的顺序排序。



  2. 算法构造
    在此论证算法设计中的一些必要的设计依据。
    (1)在保证元素多于一个的同时,取中点把元素分成两个子序列,然后将它们排好序之后进行合并:
    if (left Type* b = new Type[right - left + 1];
    int i = (left + right) / 2;
    MergeSort(a, left, i);
    MergeSort(a, i + 1, right);
    Merge(a, b, left, i, right);
    Copy(a, b, left, right);}
    (2)从第一个数据开始依次与其它的数据比较,比它小的放左边,比它大的放右边,然后在两个子序列中用同样的方法进行数据比较:
    while (i != j){
    while (a[j] >= t && j > i)
    j–;
    if (j > i)
    a[i++] = a[j];
    while (a[i] <&#061; t && j > i)
    i&#043;&#043;;
    if (j > i)
    a[j–] &#061; a[i];}



  3. 算法实现
    程序源代码&#xff08;请写入必要的注释&#xff09;。
    &#xff08;1&#xff09;合并排序
    package com.cn;
    import java.util.Arrays;
    import java.util.Scanner;
    public class OrderMerging {
    static int [] num&#061;new int[10];
    private static void FenZhi(int[] array,int left,int right,int []temp){
    if(left int mid &#061; (left&#043;right)/2;
    FenZhi(array,left,mid,temp);//左边合并排序&#xff0c;使得左边的集合有序排列
    FenZhi(array,mid&#043;1,right,temp);//右边合并排序&#xff0c;使得右边的集合有序排列
    orderMerging(array,left,mid,right,temp);//将两个有序子数组合并操作
    }
    }
    public static void BuiltArray(int []array){
    int []temp &#061; new int[array.length];//在排序前&#xff0c;先建立一个定长的数组&#xff0c;简化实现过程
    FenZhi(array,0,array.length-1,temp);
    }
    private static void orderMerging(int[] array,int left,int mid,int right,int[] temp){
    int i &#061; left;//左哨兵
    int j &#061; mid&#043;1;//分割之后的右哨兵
    int t &#061; 0;//识别数组中位置的哨兵
    while (i<&#061;mid && j<&#061;right){
    if(array[i]<&#061;array[j]){
    temp[t&#043;&#043;] &#061; array[i&#043;&#043;];
    }else {
    temp[t&#043;&#043;] &#061; array[j&#043;&#043;];
    }
    }
    while(i<&#061;mid){//将左边剩余元素放入temp中
    temp[t&#043;&#043;] &#061; array[i&#043;&#043;];
    }
    while(j<&#061;right){//将右序列剩余元素放入temp中
    temp[t&#043;&#043;] &#061; array[j&#043;&#043;];
    }
    t &#061; 0;
    //将temp中的元素全部合并到原数组中
    while(left <&#061; right){
    array[left&#043;&#043;] &#061; temp[t&#043;&#043;];
    }
    }

    public static void main(String []args){
    System.out.println(“请输入无序的数字串&#xff1a;”);
    Scanner scan&#061;new Scanner(System.in);
    for(int i&#061;0;i<&#061;9;i&#043;&#043;){
    num[i]&#061;scan.nextInt();
    }
    System.out.println(“排序后的数列如下&#xff1a;”);
    BuiltArray(num);
    System.out.println(Arrays.toString(num));

    }
    }



&#xff08;2&#xff09;快速排序
package com.cn;

public class QuickSort {

//arr 需要排序的数组
//low 开始时最左边的索引&#061;0
//high 开始时最右边的索引&#061;arr.length-1
public static void quickSort(int[] arr,int low,int high){
int i,j,temp,t;
if(low>high){
return;
}
i&#061;low;//左边哨兵的索引
j&#061;high;//右边哨兵的索引
//temp就是基准位
temp &#061; arr[low];//以最左边为 基准位

while (i //先看右边&#xff0c;依次往左递减
//先从右往左找一个小于 基准位的数
//当右边的哨兵位置所在的数>基准位的数 时
//继续从右往左找&#xff08;同时 j 索引-1&#xff09;
//找到后会跳出 while循环
while (temp<&#061;arr[j]&&i j--;
}
//再看左边&#xff0c;依次往右递增
//步骤和上面类似
while (temp>&#061;arr[i]&&i i&#043;&#043;;
}
//如果满足条件则交换
if (i

//z、y 都是临时参数&#xff0c;用于存放 左右哨兵 所在位置的数据
int z &#061; arr[i];
int y &#061; arr[j];

// 左右哨兵 交换数据&#xff08;互相持有对方的数据&#xff09;
arr[i] &#061; y;
arr[j] &#061; z;
}
}

//这时 跳出了 “while (i //说明 i&#061;j 左右在同一位置
//最后将基准为与i和j相等位置的数字交换
arr[low] &#061; arr[i];//或 arr[low] &#061; arr[j];
arr[i] &#061; temp;//或 arr[j] &#061; temp;

//i&#061;j
//这时 左半数组<(i或j所在索引的数)<右半数组
//也就是说(i或j所在索引的数)已经确定排序位置&#xff0c; 所以就不用再排序了&#xff0c;
// 只要用相同的方法 分别处理 左右数组就可以了

//递归调用左半数组
quickSort(arr, low, j-1);
//递归调用右半数组
quickSort(arr, j&#043;1, high);
}
public static void main(String[] args){
int[] arr &#061; {10,7,2,4,7,62,3,4,2,1,8,9,19};
quickSort(arr, 0, arr.length-1);
for (int i &#061; 0; i System.out.println(arr[i]);
}
}

}



  1. 运行结果
    合并拍序

快速排序
对 int[] arr &#061; {10,7,2,4,7,62,3,4,2,1,8,9,19};这个无需的数组进行排序



  1. 经验归纳
    主要是理解合并排序和快速排序的算法思想&#xff0c;是对分治思想&#xff08;分解&#xff0c;求解&#xff0c;合并&#xff09;的应用。
    &#xff08;二&#xff09;题目二&#xff1a;棋盘覆盖



  2. 题目分析
    棋盘覆盖问题需要判断特殊方块所在的位置&#xff0c;每次都对分割后的四个小方块进行判断&#xff0c;判断特殊方格是否在里面。如果特殊方块在里面&#xff0c;这直接递归下去求即可&#xff0c;如果不在&#xff0c;这根据分割的四个方块的不同位置&#xff0c;把右下角、左下角、右上角或者左上角的方格标记为特殊方块&#xff0c;然后继续递归。



  3. 算法构造
    在此论证算法设计中的一些必要的设计依据。
    定义棋盘的大小&#xff1a;size&#061;(int)pow(2.0,(int)n);
    判断算法在哪个位置&#xff08;其中一个&#xff09;&#xff1a;if (dr {
    chessBoard(tr,tc,dr,dc,s);
    }
    else
    {
    chess[tr&#043;s-1][tc&#043;s-1] &#061; t;
    chessBoard(tr,tc,tr&#043;s-1,tc&#043;s-1,s);



  4. 算法实现
    程序源代码&#xff08;请写入必要的注释&#xff09;。
    package com.cn;
    import java.util.Scanner;
    public class CheckerBoard {

    static int Board[][]&#061;new int[50][50];
    static int L&#061;1;
    public static void checkerBoard(int zsh, int zsl, int dr, int dc, int size){
    // zsh:棋盘左上角方格的行号
    // zsl:棋盘左上角方格的列号
    // dr:标记块的行号
    // dc:标记块的列号
    if(size&#061;&#061;1){ //棋盘方格大小为,说明递归到最里层
    return;
    }
    int t&#061;L&#043;&#043;; //每次都加一&#xff0c;为了显示分治的次序
    int s&#061;size/2; //将棋盘进行
    if(dr checkerBoard(zsh, zsl, dr, dc, s);
    }
    else{ //用L型快覆盖右下角
    Board[zsh&#043;s-1][zsl&#043;s-1]&#061;t;
    checkerBoard(zsh, zsl, zsh&#043;s-1, zsl&#043;s-1, s);
    }
    if(dr&#061;zsl&#043;s){ //划分右下方的棋盘
    checkerBoard(zsh, zsl&#043;s, dr, dc, s);
    }
    else{ //用L型快覆盖右下角
    Board[zsh&#043;s-1][zsl&#043;s]&#061;t;
    checkerBoard(zsh, zsl&#043;s, zsh&#043;s-1, zsl&#043;s, s);
    }
    if(dr>&#061;zsh&#043;s && dc checkerBoard(zsh&#043;s, zsl, dr, dc, s);
    }
    else{ //用L型快覆盖右上角
    Board[zsh&#043;s][zsl&#043;s-1]&#061;t;
    checkerBoard(zsh&#043;s, zsl, zsh&#043;s, zsl&#043;s-1, s);
    }
    if(dr>&#061;zsh&#043;s && dc>&#061;zsl&#043;s){ //划分右下方的棋盘
    checkerBoard(zsh&#043;s, zsl&#043;s, dr, dc, s);
    }
    else{ //用L型快覆盖左上角
    Board[zsh&#043;s][zsl&#043;s]&#061;t;
    checkerBoard(zsh&#043;s, zsl&#043;s, zsh&#043;s, zsl&#043;s, s);
    }

    }
    public static void main(String[] args) {
    int n;
    int size;//棋盘大小
    System.out.println(“请输入棋盘规格数n(n行n列)”);
    Scanner scanner&#061;new Scanner(System.in);
    n&#061;scanner.nextInt();
    int x,y;
    size&#061;(int) Math.pow(2.0,n);
    System.out.println(“请输入标记点位于的行号&#xff1a;”);
    Scanner scanner1&#061;new Scanner(System.in);
    x&#061;scanner1.nextInt()-1;
    System.out.println(“输入标记点的列号&#xff1a;”);
    Scanner scanner2&#061;new Scanner(System.in);
    y&#061;scanner2.nextInt()-1;
    checkerBoard(0,0,x,y,size);
    for(int i&#061;0;i for(int j&#061;0;j System.out.println(Board[i][j]&#043;"-");
    }
    System.out.println();
    }
    }



}
4. 运行结果



  1. 经验归纳
    主要是分治思想&#xff0c;此问题的关键是要判断出特殊方块所在的位置&#xff0c;然后运用递归把所有情况都考虑一 遍就行了。

五、实验总结
这两个实验都用到了分治思想和递归思想。
第一题合并排序是将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff0c;即先使每个子序列有序&#xff0c;再使子序列段间有序。
快速排序是通过一趟排序将要排序的数据分割成独立的两部分&#xff0c;其中一部分的所有数据都比另外一部分的所有数据都要小&#xff0c;然后再按此方法对这两部分数据分别进行快速排序&#xff0c;整个排序过程可以递归进行&#xff0c;以此达到整个数据变成有序序列。
第二题要分四种情况&#xff08;特殊方块可能在左上角、右上角、左下角、右下角&#xff09;讨论。

本文地址:https://blog.csdn.net/qq_45152962/article/details/109645643



推荐阅读
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • Ihaveaworkfolderdirectory.我有一个工作文件夹目录。holderDir.glob(*)>holder[ProjectOne, ... [详细]
  • Parity game(poj1733)题解及思路分析
    本文是对题目"Parity game(poj1733)"的解题思路进行分析。题目要求判断每次给出的区间内1的个数是否和之前的询问相冲突,如果冲突则结束。本文首先介绍了离线算法的思路,然后详细解释了带权并查集的基本操作。同时,本文还对异或运算进行了学习,并给出了具体的操作步骤。最后,本文给出了完整的代码实现,并进行了测试。 ... [详细]
  • 颜色迁移(reinhard VS welsh)
    不要谈什么天分,运气,你需要的是一个截稿日,以及一个不交稿就能打爆你狗头的人,然后你就会被自己的才华吓到。------ ... [详细]
  • 【每天三题】day 6.8
    题解参考:环形链表是否有环,求入环节点长度,求形成环的长度合并两个链表合并K个链表publicListNodemergeKLists ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
author-avatar
手机用户2502925313
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有