XJTUSE 数据结构与算法第一次作业——任务2和任务3

任务2

  1. 题目

已知一张图片是对某个事物横截面的扫描结果图,该图片的宽度是 m,高度是 n,图片的每一个像素只会由两种颜色之一构成:要么是蓝色,要么是白色。图片中的每一列的颜色分布有如下两种情形:

① 整列所有像素的颜色全是白色;

② 列中像素可以是白色或者蓝色,但在这种情况下,要么所有蓝色像素集中在从上到下,要么所有蓝色像素集中在从下到上,也就是说不会出现蓝色和白色相间的情形。

如果定义每一列的长度为蓝色像素的数量,那么如何求解图片中长度最大的列的长度呢?朴素的算法的时间复杂度是 O(mn),但该任务要求完成的算法的时间复杂度必须满足 O(mlogn).

在随实验的附件中有一个 tomography.png 图片,同学们可以使用这张图片做为测试数据,图片的大小是 1200*1600,该图片中最大列长是 1575。对图片的处理可以继续使用在面向对象程序设计课程中构建的 Picture 类型。

  1. 算法设计

题目要求算法时间复杂度是O(mlogn),可以这样理解:

将每一列视为一个数组,数组是有序的,只含有1和0两种数字,分别代表蓝色和白色,对于每一列,也就是每一个数组,需要找到它含1的个数,使用二分查找尤为方便,二分查找的时间复杂度是O(logn),这样总体的时间复杂度就是O(mlogn)。

需要注意的是,数组的前半部分可能是1,也可能是0,需要分类讨论一下。

主要的时间复杂度来源于maxRow方法中的循环,该循环遍历图像的每一列。对于每一列,都会调用getNumberOfWhite或getNumberOfBlue方法进行二分查找。

在getNumberOfWhite和getNumberOfBlue方法中,使用了二分查找来确定每一列中连续的白色或蓝色像素的数量。在最坏情况下,二分查找的时间复杂度为O(logn),其中n是图像的高度。

因此,整个算法的时间复杂度是O(mlogn),其中m是图像的宽度,n是图像的高度。

  1. 主干代码说明

maxRow方法:public方法,供外界调用。

  1. public int maxRow(Picture picture) {
  2.         //用1代表蓝色,0代表白色
  3.         int max = 0;
  4.         //查找每一列的蓝色或者白色值
  5.         for (int w = 0; w < picture.getWidth(); w++) {
  6.             //查找蓝色还是查找白色
  7.             int flag = picture.test(picture, w);
  8.             //每一列用二分查找
  9.             //照片最上面可能是蓝色,也可能是白色,如果是蓝色,那么就查蓝色的数量
  10.             if (flag == 0) {//白色
  11.                 int number;
  12.                 number = getNumberOfWhite(0, picture.getHeight() - 1, w, picture);
  13.                 if (number > max) {
  14.                     max = picture.getHeight() - number;
  15.                 }
  16.             } else if (flag == 1) {//蓝色
  17.                 int number;
  18.                 number = getNumberOfBlue(0, picture.getHeight() - 1, w, picture);
  19.                 if (number > max) {
  20.                     max = number;
  21.                 }
  22.             }
  23.         }
  24.         return max;
  25.     }

Test方法:测图片每一列第一个像素是蓝色还是白色。

  1. //仅仅是测试开始的
  2.     private int test(Picture picture, int width) {
  3.         if (picture != null && picture.getWidth() > 0 && picture.getHeight() > 0) {
  4.             Color color = picture.getColor(width, 0);
  5.             if (color != null) {
  6.                 if (color.equals(Color.BLUE)) {
  7.                     return 1;
  8.                 } else if (color.equals(Color.WHITE)) {
  9.                     return 0;
  10.                 } else {
  11.                     System.out.println("Unknown color");
  12.                     return -1;
  13.                 }
  14.             } else {
  15.                 System.out.println("Failed to get color");
  16.                 return -1;
  17.             }
  18.         } else {
  19.             System.out.println("Invalid picture");
  20.             return -1;
  21.         }
  22.     }

在主函数中先调用test方法看看能不能成功获取比较图片点的颜色,在下面的方法就不需要一直判断像素为空或者其他异常情况。

GetNumberOfWhite:当图片某列首像素是白色时,调用这个方法得到这一列白色像素的个数,那么蓝色像素个数就是width-白色像素个数即可。采用了二分法加递归。

  1. private int getNumberOfWhite(int start, int end, int width, Picture picture) {
  2.         if (start <= end) {
  3.             int mid = (start + end) / 2;
  4.             Color color = picture.getColor(width, mid);
  5.             if (color.equals(Color.WHITE)) {
  6.                 return getNumberOfWhite(mid + 1, end, width, picture);
  7.             } else if (color.equals(Color.BLUE)) {
  8.                 return getNumberOfWhite(start, mid - 1, width, picture);
  9.             }
  10.         }
  11.         return start;
  12.     }

方法GetNumberOfBlue:当图片某列首像素是蓝色时,调用这个方法得到这一列蓝色像素的个数。采用了二分法加递归。

  1. private int getNumberOfBlue(int start, int end, int width, Picture picture) {
  2.         if (start <= end) {
  3.             int mid = (start + end) / 2;
  4.             Color color = picture.getColor(width, mid);
  5.             if (color.equals(Color.BLUE)) {
  6.                 return getNumberOfBlue(mid + 1, end, width, picture);
  7.             } else if (color.equals(Color.WHITE)) {
  8.                 return getNumberOfBlue(start, mid - 1, width, picture);
  9.             }
  10.         }
  11.         return start;
  12.     }

验证方法主函数:

  1. public static void main(String[] args) throws IOException {
  2.         Picture p = new Picture("D:\\develop\\projects\\dataStructure\\homework01\\file\\tomography.png");
  3.         System.out.println(p.test(p, 1));
  4.         System.out.println(p.maxRow(p));
  5.     }

  1. 运行结果展示

第一行的0:验证能否正确读取判断像素点的颜色,答案是0,表示坐标为(0,0)的像素点是白色。

第二行的1575:表示该图片中最大列长是 1575

  1. 总结和收获

用递归和二分法去解决问题,效率很高,有很大收获,卡了很长时间的点是,数组越界了,传入参数时直接传的width而不是width-1.

任务3

  1. 题目

  1. 算法设计

6种排序算法都按课堂上讲的去实现,如下:

冒泡排序:

  1. public class Bubble extends SortAlgorithm {
  2.     /**
  3.      * 冒泡排序法
  4.      */
  5.     @Override
  6.     public void sort(Comparable[] objs) {
  7.         int N = objs.length;
  8.         for (int i = 0; i < N - 1; i++) {
  9.             //每一趟把最大的放在最右边
  10.             for (int j = 0; j < N - i - 1; j++) {
  11.                 if (less(objs[j + 1], objs[j])) {
  12.                     exchange(objs, j, j + 1);
  13.                 }
  14.             }
  15.         }
  16.     }
  17.     public void betterSort(Comparable[] objs) {
  18.         int N = objs.length;
  19.         int lastExchangeIndex = 0//记录每轮排序过程中最后发生交换操作的位置
  20.         int unOrderedEndIndex = N - 1//记录需要进行比较(无序)范围的最后位置
  21.         for (int i = 0; i < N - 1; i++) {
  22.             // 设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已经完成。
  23.             boolean flag = true;
  24.             //每一趟把最大的放在最右边
  25.             for (int j = 0; j < unOrderedEndIndex; j++) {
  26.                 if (less(objs[j + 1], objs[j])) {
  27.                     exchange(objs, j, j + 1);
  28.                     flag = false;
  29.                     lastExchangeIndex = j;
  30.                 }
  31.             }
  32.             unOrderedEndIndex = lastExchangeIndex;
  33.             if (unOrderedEndIndex == 0) {//数组已经有序
  34.                 break;
  35.             }
  36.             //这一趟完全没有交换任何元素,数组已经有序
  37.             if (flag) {
  38.                 break;
  39.             }
  40.         }
  41.     }
  42. }

选择排序:

  1. public class Selection extends SortAlgorithm {
  2.     /**
  3.      * 选择排序法
  4.      */
  5.     @Override
  6.     public void sort(Comparable[] objs) {
  7.         int N = objs.length;
  8.         for (int i = 0; i < N - 1; i++) {
  9.             int minIndex = i;
  10.             // 每一轮循环中找出最小的那个放在头部
  11.             for (int j = i + 1; j < N; j++) {
  12.                 if (less(objs[j], objs[minIndex])) {
  13.                     minIndex = j;
  14.                 }
  15.             }
  16.             exchange(objs, minIndex, i);
  17.         }
  18.     }
  19. }

插入排序:


  1. public class Insertion extends SortAlgorithm {
  2.     /**
  3.      * 插入排序法
  4.      */
  5.     @Override
  6.     public void sort(Comparable[] objs){
  7.         int N = objs.length;
  8.         for(int i = 1; i < N; i++){
  9.             for(int j = i; j > 0 && less(objs[j], objs[j-1]); j--)
  10.                 exchange(objs, j, j-1);
  11.             //在for循环中有两个条件,表示,当这两个同时满足时才进行循环体里的内容
  12.             //等价于,循环体中有if判断第二个条件,若是false则break
  13.         }
  14.     }
  15. }

希尔排序:

  1. public class Shell extends SortAlgorithm {
  2.     /**
  3.      * 希尔排序
  4.      */
  5.     @Override
  6.     public void sort(Comparable[] objs) {
  7.         //得到h
  8.         int h = 1;
  9.         while (h < objs.length / 3) {
  10.             h = h * 3 + 1;
  11.         }
  12.         //每次进行循环,改变一下h的值
  13.         while (h >= 1) {
  14.             shell(objs, h);
  15.             h /= 3;
  16.         }
  17.     }
  18.     private void shell(Comparable[] objs, int gap) {
  19.         //1.找到待插入元素(索引为i的值)
  20.         for (int i = gap; i < objs.length; i++) {//从第gap个元素开始的后续每一个连续取值
  21.             //2.将待插入元素放到有序数组中
  22.             for (int j = i; j >= gap; j -= gap) {
  23.                 //现在待插入元素是num[j]
  24.                 //比较num[j]和num[j-gap]的大小
  25.                 if (less(objs[j], objs[j - gap])) {
  26.                     exchange(objs, j, j - gap);
  27.                 } else {
  28.                     break;
  29.                 }
  30.             }
  31.         }
  32.     }
  33. }

归并排序:


  1. public class Merge extends SortAlgorithm {
  2.     /**
  3.      * 归并排序
  4.      */
  5.     Comparable[] assist;
  6.     @Override
  7.     public void sort(Comparable[] objs) {
  8.         //初始化辅助数组assist
  9.         assist = new Comparable[objs.length];
  10.         sort(objs, 0, objs.length - 1);
  11.     }
  12.     private void sort(Comparable[] objs, int low, int high) {
  13.         if (low >= high) {
  14.             return;
  15.         }
  16.         int mid = (low + high) / 2;
  17.         sort(objs, low, mid);
  18.         sort(objs, mid + 1, high);
  19.         //该合并了
  20.         merge(objs, low, mid, high);
  21.     }
  22.     private void merge(Comparable[] objs, int low, int mid, int high) {
  23.         //定义三个指针
  24.         int p1 = low;
  25.         int p2 = mid + 1;
  26.         int i = low;
  27.         //先把原数组里的排序好放到辅助数组中,再把临时数组中的值赋值回来
  28.         //遍历,移动三个指针,把小的放到assist里面
  29.         while (p1 <= mid || p2 <= high) {
  30.             if (p1 == mid + 1) {//若p1超出了mid,说明p1所在子区域已经被走了一遍
  31.                 assist[i] = objs[p2];
  32.                 p2++;
  33.             } else if (p2 == high + 1) {//若p2超出了mid,说明p2所在子区域已经被走了一遍
  34.                 assist[i] = objs[p1];
  35.                 p1++;
  36.             } else if (less(objs[p1], objs[p2])) {//当p1和p2都在对应区域内时,再判断
  37.                 assist[i] = objs[p1];
  38.                 p1++;
  39.             } else {
  40.                 assist[i] = objs[p2];
  41.                 p2++;
  42.             }
  43.             i++;
  44.         }
  45.         //拷贝
  46.         for (int index = low; index <= high; index++) {
  47.             objs[index] = assist[index];
  48.         }
  49.     }
  50. }

快速排序:


  1. public class Quick extends SortAlgorithm {
  2.     /**
  3.      * 快速排序
  4.      */
  5.     @Override
  6.     public void sort(Comparable[] objs) {
  7.         sort(objs, 0, objs.length - 1);
  8.     }
  9.     public void sort(Comparable[] objs, int left, int right) {
  10.         if (left < right) {
  11.             int pivotIndex = partition(objs, left, right);
  12.             sort(objs, left, pivotIndex - 1);
  13.             sort(objs, pivotIndex + 1, right);
  14.         }
  15.     }
  16.     private int partition(Comparable[] objs, int left, int right) {
  17.         Comparable pivot = objs[right];
  18.         int i = left - 1;
  19.         for (int j = left; j < right; j++) {
  20.             if (less(objs[j], pivot)) {
  21.                 i++;
  22.                 exchange(objs, i, j);
  23.             }
  24.         }
  25.         exchange(objs, i + 1, right);
  26.         return i + 1;
  27.     }
  28. }

测试方法:

  1. public static void main(String[] args) {
  2.         //冒泡排序
  3.         Double[] numbers_1 = GenerateData.getRandomData(1000);
  4.         SortAlgorithm bubbleAlg = new Bubble();
  5.         bubbleAlg.sort(numbers_1);
  6.         System.out.print("冒泡排序:");
  7.         System.out.println(bubbleAlg.isSorted(numbers_1));
  8.         //选择排序
  9.         Double[] numbers_2 = GenerateData.getRandomData(1000);
  10.         SortAlgorithm selectionAlg  = new Selection();
  11.         selectionAlg.sort(numbers_2);
  12.         System.out.print("选择排序:");
  13.         System.out.println(selectionAlg.isSorted(numbers_2));
  14.         //插入排序
  15.         Double[] numbers_3 = GenerateData.getRandomData(1000);
  16.         SortAlgorithm insertionAlg  = new Insertion();
  17.         insertionAlg.sort(numbers_3);
  18.         System.out.print("插入排序:");
  19.         System.out.println(insertionAlg.isSorted(numbers_3));
  20.         //希尔排序
  21.         Double[] numbers_4 = GenerateData.getRandomData(1000);
  22.         SortAlgorithm shellAlg  = new Shell();
  23.         shellAlg.sort(numbers_4);
  24.         System.out.print("希尔排序:");
  25.         System.out.println(shellAlg.isSorted(numbers_4));
  26.         //归并排序
  27.         Double[] numbers_5 = GenerateData.getRandomData(1000);
  28.         SortAlgorithm mergeAlg  = new Merge();
  29.         mergeAlg.sort(numbers_5);
  30.         System.out.print("归并排序:");
  31.         System.out.println(mergeAlg.isSorted(numbers_5));
  32.         //快速排序
  33.         Double[] numbers_6 = GenerateData.getRandomData(1000);
  34.         SortAlgorithm quickAlg  = new Quick();
  35.         quickAlg.sort(numbers_6);
  36.         System.out.print("快速排序:");
  37.         System.out.println(quickAlg.isSorted(numbers_6));
  38.     }
  1. 运行结果展示

  1. 总结和收获

对各种排序算法更加熟练,掌握的更好。

附录:

  1. 任务2
  1. import javax.imageio.ImageIO;
  2. import java.awt.*;
  3. import java.awt.image.BufferedImage;
  4. import java.io.File;
  5. import java.io.IOException;
  6. public class Picture {
  7.     private BufferedImage image;
  8.     private int width;
  9.     private int height;
  10.     public Picture(String filename) throws IOException {
  11.         File file = new File(filename);
  12.         image = ImageIO.read(file);
  13.         width = image.getWidth();
  14.         height = image.getHeight();
  15.     }
  16.     public Picture(int width, int height) {
  17.         this.width = width;
  18.         this.height = height;
  19.         image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
  20.     }
  21.     public int getWidth() {
  22.         return width;
  23.     }
  24.     public int getHeight() {
  25.         return height;
  26.     }
  27.     public void setColor(int col, int row, Color c) {
  28.         image.setRGB(col, row, c.getRGB());
  29.     }
  30.     public Color getColor(int col, int row) {
  31.         int rgb = image.getRGB(col, row);
  32.         return new Color(rgb);
  33.     }
  34.     public void save(String filename) throws IOException {
  35.         String suffix = filename.substring(filename.lastIndexOf('.') + 1);
  36.         if (suffix.equalsIgnoreCase("png") || suffix.equalsIgnoreCase("jpg"))
  37.             ImageIO.write(image, suffix, new File(filename));
  38.     }
  39.     public void darker() {
  40.         for (int i = 0; i < width; i++)
  41.             for (int j = 0; j < height; j++) {
  42.                 Color c = getColor(i, j);
  43.                 setColor(i, j, c.darker());
  44.             }
  45.     }
  46.     public int maxRow(Picture picture) {
  47.         //用1代表蓝色,0代表白色
  48.         int max = 0;
  49.         //查找每一列的蓝色或者白色值
  50.         for (int w = 0; w < picture.getWidth(); w++) {
  51.             //查找蓝色还是查找白色
  52.             int flag = picture.test(picture, w);
  53.             //每一列用二分查找
  54.             //照片最上面可能是蓝色,也可能是白色,如果是蓝色,那么就查蓝色的数量
  55.             if (flag == 0) {//白色
  56.                 int number;
  57.                 number = getNumberOfWhite(0, picture.getHeight() - 1, w, picture);
  58.                 if (number > max) {
  59.                     max = picture.getHeight() - number;
  60.                 }
  61.             } else if (flag == 1) {//蓝色
  62.                 int number;
  63.                 number = getNumberOfBlue(0, picture.getHeight() - 1, w, picture);
  64.                 if (number > max) {
  65.                     max = number;
  66.                 }
  67.             }
  68.         }
  69.         return max;
  70.     }
  71.     //仅仅是测试开始的
  72.     private int test(Picture picture, int width) {
  73.         if (picture != null && picture.getWidth() > 0 && picture.getHeight() > 0) {
  74.             Color color = picture.getColor(width, 0);
  75.             if (color != null) {
  76.                 if (color.equals(Color.BLUE)) {
  77.                     return 1;
  78.                 } else if (color.equals(Color.WHITE)) {
  79.                     return 0;
  80.                 } else {
  81.                     System.out.println("Unknown color");
  82.                     return -1;
  83.                 }
  84.             } else {
  85.                 System.out.println("Failed to get color");
  86.                 return -1;
  87.             }
  88.         } else {
  89.             System.out.println("Invalid picture");
  90.             return -1;
  91.         }
  92.     }
  93.     public static void main(String[] args) throws IOException {
  94.         Picture p = new Picture("D:\\develop\\projects\\dataStructure\\homework01\\file\\tomography.png");
  95.         System.out.println(p.test(p, 1));
  96.         System.out.println(p.maxRow(p));
  97.     }
  98.     private int getNumberOfWhite(int start, int end, int width, Picture picture) {
  99.         if (start <= end) {
  100.             int mid = (start + end) / 2;
  101.             Color color = picture.getColor(width, mid);
  102.             if (color.equals(Color.WHITE)) {
  103.                 return getNumberOfWhite(mid + 1, end, width, picture);
  104.             } else if (color.equals(Color.BLUE)) {
  105.                 return getNumberOfWhite(start, mid - 1, width, picture);
  106.             }
  107.         }
  108.         return start;
  109.     }
  110.     private int getNumberOfBlue(int start, int end, int width, Picture picture) {
  111.         if (start <= end) {
  112.             int mid = (start + end) / 2;
  113.             Color color = picture.getColor(width, mid);
  114.             if (color.equals(Color.BLUE)) {
  115.                 return getNumberOfBlue(mid + 1, end, width, picture);
  116.             } else if (color.equals(Color.WHITE)) {
  117.                 return getNumberOfBlue(start, mid - 1, width, picture);
  118.             }
  119.         }
  120.         return start;
  121.     }
  122. }

  1. 任务3
  1. public class Insertion extends SortAlgorithm {
  2.     /**
  3.      * 插入排序法
  4.      */
  5.     @Override
  6.     public void sort(Comparable[] objs){
  7.         int N = objs.length;
  8.         for(int i = 1; i < N; i++){
  9.             for(int j = i; j > 0 && less(objs[j], objs[j-1]); j--)
  10.                 exchange(objs, j, j-1);
  11.             //在for循环中有两个条件,表示,当这两个同时满足时才进行循环体里的内容
  12.             //等价于,循环体中有if判断第二个条件,若是false则break
  13.         }
  14.     }
  15. }

  1. public class Bubble extends SortAlgorithm {
  2.     /**
  3.      * 冒泡排序法
  4.      */
  5.     @Override
  6.     public void sort(Comparable[] objs) {
  7.         int N = objs.length;
  8.         for (int i = 0; i < N - 1; i++) {
  9.             //每一趟把最大的放在最右边
  10.             for (int j = 0; j < N - i - 1; j++) {
  11.                 if (less(objs[j + 1], objs[j])) {
  12.                     exchange(objs, j, j + 1);
  13.                 }
  14.             }
  15.         }
  16.     }
  17. }

  1. public class Selection extends SortAlgorithm {
  2.     /**
  3.      * 选择排序法
  4.      */
  5.     @Override
  6.     public void sort(Comparable[] objs) {
  7.         int N = objs.length;
  8.         for (int i = 0; i < N - 1; i++) {
  9.             int minIndex = i;
  10.             // 每一轮循环中找出最小的那个放在头部
  11.             for (int j = i + 1; j < N; j++) {
  12.                 if (less(objs[j], objs[minIndex])) {
  13.                     minIndex = j;
  14.                 }
  15.             }
  16.             exchange(objs, minIndex, i);
  17.         }
  18.     }
  19. }

  1. public class Shell extends SortAlgorithm {
  2.     /**
  3.      * 希尔排序
  4.      */
  5.     @Override
  6.     public void sort(Comparable[] objs) {
  7.         //得到h
  8.         int h = 1;
  9.         while (h < objs.length / 3) {
  10.             h = h * 3 + 1;
  11.         }
  12.         //每次进行循环,改变一下h的值
  13.         while (h >= 1) {
  14.             shell(objs, h);
  15.             h /= 3;
  16.         }
  17.     }
  18.     private void shell(Comparable[] objs, int gap) {
  19.         //1.找到待插入元素(索引为i的值)
  20.         for (int i = gap; i < objs.length; i++) {//从第gap个元素开始的后续每一个连续取值
  21.             //2.将待插入元素放到有序数组中
  22.             for (int j = i; j >= gap; j -= gap) {
  23.                 //现在待插入元素是num[j]
  24.                 //比较num[j]和num[j-gap]的大小
  25.                 if (less(objs[j], objs[j - gap])) {
  26.                     exchange(objs, j, j - gap);
  27.                 } else {
  28.                     break;
  29.                 }
  30.             }
  31.         }
  32.     }
  33. }


  1. public class Merge extends SortAlgorithm {
  2.     /**
  3.      * 归并排序
  4.      */
  5.     Comparable[] assist;
  6.     @Override
  7.     public void sort(Comparable[] objs) {
  8.         //初始化辅助数组assist
  9.         assist = new Comparable[objs.length];
  10.         sort(objs, 0, objs.length - 1);
  11.     }
  12.     private void sort(Comparable[] objs, int low, int high) {
  13.         if (low >= high) {
  14.             return;
  15.         }
  16.         int mid = (low + high) / 2;
  17.         sort(objs, low, mid);
  18.         sort(objs, mid + 1, high);
  19.         //该合并了
  20.         merge(objs, low, mid, high);
  21.     }
  22.     private void merge(Comparable[] objs, int low, int mid, int high) {
  23.         //定义三个指针
  24.         int p1 = low;
  25.         int p2 = mid + 1;
  26.         int i = low;
  27.         //先把原数组里的排序好放到辅助数组中,再把临时数组中的值赋值回来
  28.         //遍历,移动三个指针,把小的放到assist里面
  29.         while (p1 <= mid || p2 <= high) {
  30.             if (p1 == mid + 1) {//若p1超出了mid,说明p1所在子区域已经被走了一遍
  31.                 assist[i] = objs[p2];
  32.                 p2++;
  33.             } else if (p2 == high + 1) {//若p2超出了mid,说明p2所在子区域已经被走了一遍
  34.                 assist[i] = objs[p1];
  35.                 p1++;
  36.             } else if (less(objs[p1], objs[p2])) {//当p1和p2都在对应区域内时,再判断
  37.                 assist[i] = objs[p1];
  38.                 p1++;
  39.             } else {
  40.                 assist[i] = objs[p2];
  41.                 p2++;
  42.             }
  43.             i++;
  44.         }
  45.         //拷贝
  46.         for (int index = low; index <= high; index++) {
  47.             objs[index] = assist[index];
  48.         }
  49.     }
  50. }

  1. public class Quick extends SortAlgorithm {
  2.     /**
  3.      * 快速排序
  4.      */
  5.     @Override
  6.     public void sort(Comparable[] objs) {
  7.         sort(objs, 0, objs.length - 1);
  8.     }
  9.     public void sort(Comparable[] objs, int left, int right) {
  10.         while (left < right) {
  11.             int pivotIndex = partition(objs, left, right);
  12.             if (pivotIndex - left < right - pivotIndex) {
  13.                 // 左侧较短
  14.                 sort(objs, left, pivotIndex - 1);
  15.                 left = pivotIndex + 1;
  16.             } else {
  17.                 // 右侧较短
  18.                 sort(objs, pivotIndex + 1, right);
  19.                 right = pivotIndex - 1;
  20.             }
  21.         }
  22.     }
  23.     private int partition(Comparable[] objs, int left, int right) {
  24.         int i = left, j = right;
  25.         Comparable pivot = objs[left]; // 选择第一个元素作为基准数
  26.         while (i < j) {
  27.             while (i < j && less(pivot, objs[j]))
  28.                 j--;
  29.             if (i < j)
  30.                 objs[i++] = objs[j];
  31.             while (i < j && !less(pivot, objs[i]))
  32.                 i++;
  33.             if (i < j)
  34.                 objs[j--] = objs[i];
  35.         }
  36.         objs[i] = pivot;
  37.         return i;
  38.     }
  39. }

测试方法:

  1. public static void main(String[] args) {
  2.         //冒泡排序
  3.         Double[] numbers_1 = GenerateData.getRandomData(1000);
  4.         SortAlgorithm bubbleAlg = new Bubble();
  5.         bubbleAlg.sort(numbers_1);
  6.         System.out.print("冒泡排序:");
  7.         System.out.println(bubbleAlg.isSorted(numbers_1));
  8.         //选择排序
  9.         Double[] numbers_2 = GenerateData.getRandomData(1000);
  10.         SortAlgorithm selectionAlg  = new Selection();
  11.         selectionAlg.sort(numbers_2);
  12.         System.out.print("选择排序:");
  13.         System.out.println(selectionAlg.isSorted(numbers_2));
  14.         //插入排序
  15.         Double[] numbers_3 = GenerateData.getRandomData(1000);
  16.         SortAlgorithm insertionAlg  = new Insertion();
  17.         insertionAlg.sort(numbers_3);
  18.         System.out.print("插入排序:");
  19.         System.out.println(insertionAlg.isSorted(numbers_3));
  20.         //希尔排序
  21.         Double[] numbers_4 = GenerateData.getRandomData(1000);
  22.         SortAlgorithm shellAlg  = new Shell();
  23.         shellAlg.sort(numbers_4);
  24.         System.out.print("希尔排序:");
  25.         System.out.println(shellAlg.isSorted(numbers_4));
  26.         //归并排序
  27.         Double[] numbers_5 = GenerateData.getRandomData(1000);
  28.         SortAlgorithm mergeAlg  = new Merge();
  29.         mergeAlg.sort(numbers_5);
  30.         System.out.print("归并排序:");
  31.         System.out.println(mergeAlg.isSorted(numbers_5));
  32.         //快速排序
  33.         Double[] numbers_6 = GenerateData.getRandomData(1000);
  34.         SortAlgorithm quickAlg  = new Quick();
  35.         quickAlg.sort(numbers_6);
  36.         System.out.print("快速排序:");
  37.         System.out.println(quickAlg.isSorted(numbers_6));
  38.     }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值