算法二 递归与分治策略

广东金融学院实验报告

课程名称:算法分析与设计

 

装订线

实验编号

 

及实验名称

实验2 递归与分治策略

系 别

互联网金融与信息工程

姓   名

陈艺瀚

学    号

161616134

班  级

1615432

实验地点

5-503

实验日期

2018-10-8

实验时数

1

指导教师

 郭艺辉

同组其他成员

成  绩

 

  • 实验目的及要求
  1. 理解递归的概念以及递归调用工作原理;
  2. 掌握分治法基本思想、设计模式;
  3. 掌握算法最坏时间复杂性计算方法;
  4. 掌握二分搜索技术以及基于分治策略的排序算法。
  • 实验环境及相关情况(包含使用软件、实验设备、主要仪器及材料等)
  1. 主要仪器:微型计算机,55台,每人一台。
  2. 软件环境:Eclipse 3.0.1 SDK。
  • 实验内容及步骤(包含简要的实验步骤流程)
  1. 简答题
  1. 什么是递归函数?什么是递归算法?
  2. 简述递归调用的工作原理。
  3. 简述分治法的基本思想及一般算法设计模式。
  4. 简述合并排序基本思想,并对合并排序算法做时间复杂性分析。
  5. 简述快速排序基本思想,并对快速排序算法做时间复杂性分析。
  1. 算法设计与分析题
  1. 给定数组a[0:8]={-15,-6,0,7,9,23,54,82,101}。请改写二分搜索算法,使得当待搜索元素x=30不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j。将算法编程实现,并将程序与运行结果填写在“四、实验结果”。
  2. 给定数组a[]={8,4,3,7,1,5,6,2},使用基于分治策略的快速排序算法对其进行排序,将算法编程实现,并将程序与运行结果填写在“四、实验结果”。
  3. 快速排序算法的性能与划分是否对称有关,设计随机化的快速排序算法解决划分对称性问题,将算法编程实现;并回答:对于一个随机化算法,为什么只分析其平均情况下的性能,而不分析其最坏情况下的性能?

 

四、实验结果(包括程序或图表、结论陈述、数据记录及分析等,可附页)

  1.  
  1. 递归函数:函数直接或间接地调用函数本身。

递归算法:在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。

  1. 递归的基本原理

第一:每一级的函数调用都有它自己的变量。

第二:每一次函数调用都会有一次返回,并且是某一级递归返回到调用它的那一级,而不是直接返回到main()函数中的初始调用部分。

第三:递归函数中,位于递归调用前的语句和各级被调函数具有相同的执行顺序。

第四:递归函数中,位于递归调用后的语句的执行顺序和各个被调函数的顺序相反。

第五:虽然每一级递归都有自己的变量,但是函数代码不会复制。

第六:递归函数中必须包含终止递归的语句。通常递归函数会使用一个if条件语句或其他类似语句一边当函数参数达到某个特定值时结束递归调用。

  1. 分治策略的基本思想其基本思想是:分治法将问题分成一些小的问题然后递归求解,而治的阶段则将分的阶段得到的各答案”修补”在一起,即分而治之

一般算法的设计模式:采用分治策略,先分后合:将待排序的n个元素分成大小相同的两个集合,递归的调用此方法,只到子集合剩下一个元素,停止分割。再将分割后的两个子集合合并在一起。

  1. 合并排序(归并排序)算法是用分治策略实现对n个元素进行排序的算法。其基本思想是:将待排序元素分成大小相同的2个集合,分别对2个集合进行排序,最终将排好序的子集合合并为所要求的排好序的集合。

合并排序先将待排序元素分成大小一致的2个子集合,分别对2个子集合排序,最终合并2个排好序的数组段到新的数组temp中,然后copy数组回原来的数组arr中。

合并排序算法对n个元素进行排序,在最坏情况下所需的计算时间T(n)满足:

T(n)=2T(n/2)+O(n),n>1

即时间复杂度为O(nlog(n))

  1. 快速排序的基本思想:从待排序的数列中选择一个数作为基准点,将比基准点小的数全放在它左边,比它大的数全放在它右边。再对左右区间重复上述步骤,直到区间内只剩下一个元素。时间复杂度为O(nlog(n))

(1)

 

   

public class BinarySort {

    public static void main(String[] args) {

        int[] arr = {-15, -6, 0, 7, 9, 23, 54, 82, 101};

        int x =-16;

        int middle=findLast(arr,0,arr.length-1,x);

        int middle1=findFirst(arr,0,arr.length-1,x);

        System.out.println(middle+”,”+middle1);

}

   public static int findLastLE(int[] arr, int left, int right, int x) {

        while (left <= right) {

            int middle = (right + left) / 2;

            if (arr[middle] < x) {

                left = middle + 1;

            } else {

                right = middle – 1;

            }

        }

        if (right < 0)//数值不在数组内,则没有小于改数的最大下标

        {

            return -1;

        }

        return left – 1;

    }

 

    public static int findFirstGE(int[] arr, int left, int right, int x) {

        while (left <= right) {

            int middle = (right + left) / 2;

            if (arr[middle] < x) {

                left = middle + 1;

            } else {

                right = middle – 1;

            }

        }

        if (left > arr.length – 1)//数值不在数组内,则没有大于改数的最小下标

        {

            return -1;

        }

        return right + 1;

    }

 

 

2.

package Sort;

import java.util.Arrays;

public class QuickSort {

public static void main(String[] args)

{

    int[] arr={8,4,3,7,1,5,6,2};

    quickSort(0, arr.length-1, arr);

    System.out.println(Arrays.toString(arr));

   

}

public static void quickSort(int left,int right,int

        [] arr)

{

    if(left>=right)

    {

        return;

    }

 

    int temp=arr[left];

    int i=left;

    int j=right;

   

    while(i<j)

    {

        while(i<j&&arr[j]>=temp)

        {

           j–;

        }

        while(i<j&&arr[i]<=temp)

        {

           i++;

        }

        if(i<j)

        {

           int temp2=arr[j];

           arr[j]=arr[i];

           arr[i]=temp2;

        }  

       

    }

    arr[left]=arr[i];

    arr[i]=temp;

   

    quickSort(left,i-1,arr);

    quickSort(i+1,right,arr);         

}

}

  1. 因为快速排序随机算法是随机以一个数为基准点,出现左集合为空或由集合为空的可能性很小,所以只分析其平均情况下的性能,而不分析其最坏情况下的性能。

 

    public static void main(String[] args)

    {

        int[] arr={5,3,1,9,8,2,4,7};

        quick(arr,0,arr.length-1);

        System.out.println(Arrays.toString(arr));

    }

    public static void quick(int[] arr,int left,int right)

    {

        while (left>=right)

        {

            return;

        }

        int i=left;

        int j=right;

        int k=(int)(Math.random()*(right-left+1))+left;//从数组中随机选择一个数作为基准点

        int temp=arr[k];

        arr[k]=arr[left];

        arr[left]=temp;//将以基准点放在数组下标为0的位置–》容易判断

        int firstIndex=left;

        int first=arr[firstIndex];

        while (i<j)

        {

            while (i<j&&arr[j]>=first)

            {

                j–;

            }

            while (i<j&&arr[i]<=first)

            {

 

               i++;

            }

            if(i<j)

            {

                int temp2=arr[j];

                arr[j]=arr[i];

                arr[i]=temp2;

            }

        }

        arr[firstIndex]=arr[i];

        arr[i]=first;

        quick(arr,left,i-1);

        quick(arr,i+1,right);

    }

  1. 实验总结(包括心得体会、问题回答及实验改进意见,可附页)

本次实验我懂得了归并排序算法是采用分治策略实现,同时知道了递归函数是一种直接或间接地调用自己的函数,快速排序和归并排序都是排序较快,时间复杂度较低的算法。

六、教师评语

1、完成所有规定的实验内容,实验步骤正确,结果正确;

2、完成绝大部分规定的实验内容,实验步骤正确,结果正确;

3、完成大部分规定的实验内容,实验步骤正确,结果正确;

4、基本完成规定的实验内容,实验步骤基本正确,所完成的结果基本正确;

5、未能很好地完成规定的实验内容或实验步骤不正确或结果不正确。

6、其它:                                                             

 

                   评定等级:优秀  良好  中等  及格  不及格

教师签名:郭艺辉

2018年09月19日

          

 

 

    原文作者:递归与分治算法
    原文地址: https://blog.csdn.net/cyhgogogo/article/details/83446827
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞