《算法(第四版)》2.1部分习题

算法之路漫漫,还只是个初学者,仅做笔记,有很多不好的地方提前致歉。
代码都已上传到git/github,其中包括在力扣上的一些题解(目前较少)以及笔记。

git:https://gitee.com/yayako/algorithm.git

github:https://github.com/yayakoBlessing/algorithm.git

官方库jar包已上传至百度云

链接:https://pan.baidu.com/s/182L-CZHq–NimCPii95zAg
提取码:xgxb

算法比较 封装

为了方面,算法比较的方法封装的比较麻烦。

/**
 * 算法比较(基于不同算法对同一数组的排序的用时比较)
 *
 * @param s 名称
 * @param baseSorts 算法类
 */
public static void timeRandomInput(String[] s, BaseSort[] baseSorts) {
   
  List<Comparable[]> a = new ArrayList<>(T);
  Comparable[] b;
  double[] total, pre = new double[s.length];
  int n;

  //    // 专为 2.1.27 使用,生成从2^7~2^16长度的测试数组
  //    for (int i = 7; i <= 16; i++) {
   
  //      n = (int) Math.pow(2, i);

  // 生成从100~100000数量级长度的测试数组
  for (int i = 2; i <= 5; i++) {
   
    n = (int) Math.pow(10, i);
    System.out.println();
    System.out.println("ArraySize = " + n);
    // 每个数量级的排序都要分别进行T次,所以需要初始化T个相同长度的不同数组
    for (int j = 0; j < T; j++) {
   
      b = ArrayGenerate.random(n);
      a.add(b);
    }
    total = SortCompare.compare(baseSorts, a, n);
    for (int k = 0; k < baseSorts.length; k++) {
   
      System.out.println(s[k] + ":" + total[k] + "\tnow/pre = " + total[k] / pre[k]);
      pre[k] = total[k];
    }
    a.clear();
  }
}

/**
 * 综合比较
 *
 * @param baseSorts 需要进行比较的各算法类型
 * @param a 排序对象数组
 * @param n 数组长度
 * @return 用时数组
 */
public static double[] compare(BaseSort[] baseSorts, List<Comparable[]> a, int n) {
   
  Comparable[] b;
  int j;
  double[] total = new double[baseSorts.length];
  for (int i = 0; i < T; i++) {
   
    b = new Comparable[n];
    j = 0;
    for (BaseSort baseSort : baseSorts) {
   
      System.arraycopy(a.get(i), 0, b, 0, n);
      total[j++] = SortCompare.time(baseSort, b);
    }
  }
  return total;
}


/** 构造随机数组 */
public static Comparable[] random(int n) {
   
  Comparable[] a = new Comparable[n];
  for (int i = 0; i < n; i++) a[i] = Math.random() * 100;
  return a;
}

2.1.11

题目

将希尔排序中实时计算递增序列改为预先计算并存储在一个数组中。

评估

数组长度从100~100000数量级长度,各排序分别执行5次取其总用时

预先计算递增序列并存储在一个数组的方式只能在对小规模数组进行排序时有所优化。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UNpb8sih-1580643882763)(C:\Users\90598\AppData\Roaming\Typora\typora-user-images\image-20200202155553974.png)]

代码实现

Math.log(2 * (n / 3) + 1) / Math.log(3)) + 1 这个是用数组规律算出来的长度

/**
 * 将希尔排序中实时计算递增序列改为预先计算并存储在一个数组中。
 *
 * @author cyy
 */
public class ex11 implements BaseSort {
   

  public static void main(String[] args) {
   
    String[] s = {
   "原版用时", "改版用时"};
    BaseSort[] baseSorts = {
   new Shell(), new ex11()};

    SortCompare.timeRandomInput(s, baseSorts);
  }

  @Override
  public void sort(Comparable[] a) {
   
    int n = a.length;
    int i, j, h, k;
    int[] tmp = new int[(int) (Math.log(2 * (n / 3) + 1) / Math.log(3)) + 1];
    for (i = 0, h = 1; i < tmp.length; i++, h = 3 * h + 1) tmp[i] = h;
    for (k = 0; k < tmp.length; k++) {
   
      for (i = h = tmp[k]; i < n; i++)
        for (j = i; j >= h && Common.less(a[j], a[j - h]); j -= h) Common.exch(a, j - h, j);
    }
  }
}

2.1.12

题目

令希尔排序打印出递增序列的每个元素所带来的比较次数和数组大小的比值。
编写一个测试用例对随机 Double 数组进行希尔排序,验证该值是一个小常数,数组大小按照 10 的幂次递增,不小于 100。

评估

代码实现

/**
 * 令希尔排序打印出递增序列的每个元素所带来的比较次数和数组大小的比值。
 *
 * <p>编写一个测试用例对随机 Double 数组进行希尔排序,验证该值是一个小常数,数组大小按照 10 的幂次递增,不小于 100。
 *
 * @author cyy
 */
public class ex12 {
   

  private static void sort(Comparable[] a) {
   
    int N = a.length;
    System.out.println();
    System.out.println("ArraySize = " + N);
    int h = 1;
    while (h < N / 3) h = 3 * h + 1;
    int i, j, ctime;
    while (h >= 1) {
   
      ctime = 0;
      for (i = h; i < N; i++) {
   
        for (j = i; j >= h && less(a[j], a[j - h]); j -= h, ctime++) {
   
          exch(a, j - h, j);
        }
      }
      System.out.println(
          "CompareTimeOf h ="
              + h
              + ":"
              + ctime
              + "\t\tCompareTime/ArraySize = "
              + ((float) ctime / N));
      h /= 3;
    }
  }

  public static void main(String[] args) {
   
    for (int i = 2; i < 6; i++) {
   
      sort(ArrayGenerate.randomDouble((int) Math.pow(10, i)));
    }
  }
}

2.1.24

题目

插入排序的哨兵。
在插入排序的实现中先找出最小的元素并将其置于数组的最左边,这样就能去掉内循环的判断条件 j>0。
使用 SortCompare 来评估这种做法的效果。
注意:这是一种常见的规避边界测试的方法,能够省略判断条件的元素通常称为哨兵。

评估

数组长度从100~100000数量级长度,各排序分别执行5次取其总用时

改版后的插入排序性能有所提升[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fj719JLE-1580643807322)(C:\Users\90598\AppData\Roaming\Typora\typora-user-images\image-20200202183503212.png)]

代码实现

/**
 * 插入排序的哨兵。 在插入排序的实现中先找出最小的元素并将其置于数组的最左边,这样就能去掉内循环的判断条件 j>0。 使用 SortCompare 来评估这种做法的效果。
 * 注意:这是一种常见的规避边界测试的方法,能够省略判断条件的元素通常称为哨兵。
 *
 * @author cyy
 */
public class ex24 implements BaseSort {
   

  public static void main(String[] args) {
   
    String[] s = {
   "原版用时", "改版用时"};
    BaseSort[] baseSorts = {
   new Insertion(), new ex24()};

    SortCompare.timeRandomInput(s, baseSorts);
  }

  @Override
  public void sort(Comparable[] a) {
   
    int n = a.length;
    int i, min = 0;
    for (i = 0; i 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值