数据结构与算法【1 万条数据量测试排序算法】

1 万条数据量测试排序算法

在 ArrayGenerator 类中实现 generateOrderedArray() 这样的 顺序数组的方法 去将

generateRandomArray() 提供的乱序数组进行排序

但是我们提供的数据肯定是乱序的 才要进行排序

我们为了提供乱序的数据 设置方法 generateRandomArray() 也就是生成随机数组(无序数组)

generateRandomArray() ===> 生成随机数组 ====> generateOrderedArray 去排序 =====>返回结果给ArrayGenerator

package src;
import java.util.Random;
/**
* @author xxz
* @version 1.0
* @Created on: 2024-01-17 13:37
* @Description: 使用整形Integer这个数据类型进行测试
*/
public class ArrayGenerator {

   private ArrayGenerator(){}
   // generateOrderedArray将 generateRandomArray随机生成的数组 进行顺序排序
   public static Integer[] generateOrderedArray(int n){
          Integer[] arr = new Integer[n];
       for (int i = 0; i < n; i++)
           arr[i] = i;
           return arr;

   }
   // 生成一个长度为 n 随机数组,每个数字的范围是 [0,bound)
   // 设置随机生成数组【乱序】的 generateRandomArray方法 并也返回 Integer 类型的数组
   public static Integer[] generateRandomArray(int n, int bound) {
       Integer[] arr = new Integer[n];  // 设置随机生成的数组大小n
       Random rnd = new Random();  // 使用Random 来生成随机的数值
       for (int i = 0; i < n; i++)
           arr[i] = rnd.nextInt(bound);  //  bound 为随机数生成的最大的那个边界在那里
       // 这一步是为数组的第i个元素赋予一个随机生成的整数值。 
       // `rnd.nextInt(bound)` 是使用`Random`对象(在这里是`rnd`)生成一个随机的整数值。
       // `bound` 参数指定了生成的随机数的上限,即生成的随机数将在0(包括)到`bound`(不包括)之间。
       // 将生成的随机数赋值给数组`arr`的第i个元素,即 `arr[i] = rnd.nextInt(bound);
       // 可以在数组中的每个位置都存储一个随机生成的整数,这些整数的范围在0到`bound-1`之间。
       return arr;
   }
}

接下来就可以使用 这个随机生成数组的方法了 我们要的数据量的大小 通过定义n 来确定

package src;

public class SelectionSort_04 {
    private SelectionSort_04(){}
    public static <E extends Comparable<E>> void sort (E [] arr){ //进行实现 Comparable 接口来实现泛型可以进行1比较
        for (int i = 0; i < arr.length; i++) {
            int minIndex = i ;
            // 选择 arr[i...n]中最小的索引
            for(int j = i; j<arr.length; j++){
                if (arr[j].compareTo(arr[minIndex])<0)
                    minIndex = j;
            }
            swap(arr, i ,minIndex);
        }
    }
    //修改  swap方法 为泛型方法
    private static <E> void swap(E [] arr, int i ,int j){
        E t  = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }
    
      // 测试 1万数据量
      public static void main(String[] args) {
        // 设定测试数据最大量为1万
        int n = 10000;
          // 随机生成数组的参数1是最大容量和数组大小都设定为1万    ArrayGenerator 类只是提供了随机生成数组的方法
        Integer[] arr = ArrayGenerator.generateRandomArray(n,n);
            // 为了记录算法对数据的排序耗时  在排序进行前和后进行记录时间戳
          long startTime = System.nanoTime(); // 开始时间
          // 使用上面的排序算法进行排序
          SelectionSort_04.sort(arr);
          long endTime = System.nanoTime();   // 结束时间

          //换算时间 time 来接受 结果
          double time =  (endTime - startTime) / 1000000000.0;
          System.out.println("测试1万条数据进行排序花费时间"+time+ " 秒");
      }
}

image-20240117141605810

这里没有进行 算法执行完 对生成的排序数组的验证 只是求得算法执行的时间性能 不够严谨 !!!!!

继续优化:

这样执行完我们只得到了算法执行完的时间 但是我们到底排序是否正确呢?

我们就会思考 :

那我们执行完 我们需要对我们执行的结果进行验证,来检验结果是否正确 不然只有性能时间 不能证明算法执行的是我们想要的结果 应该怎么做呢?

我们在数据量小的时候 可以进行控制台打印 用肉眼直观的看是正确 那现在 1万条数据我们总不能一个一个打印去看排序结果是否排序正确吧 那怎么处理呢?

思路:

我们只需要验证一下 这个生成的数组是不是有序的 无论是升序还是降序 只要有序 那我们排序算法就是正确的 这样验证性能时间才是正确的

也就是说 我们 将执行完排序的 数组 从头到尾的扫描比对一下 每两个相邻的数据元素 是否都满足 前一个元素是否都 小于 后一个元素 要是满足 我们排序算法就是

正确的 。

我们来做这个步骤:

将验证封装进方法 当使用的时候去调用 判断数组是否有序的方法

起名:SortingHelper 辅助验证排序算法结果是否正确

思路:将执行完排序得到的数组 从头到尾的扫描比对一下 每两个相邻的数据元素 是否都满足 前一个元素是否都 小于 后

一个元素

package src;
/**
 * @author xxz
 * @version 1.0
 * @Created on: 2024-01-17 14:26
 * @Description: 辅助验证排序算法是否正确 
 */
public class   {
    private SortingHelper() {}
    // 返回值为布尔值 true false  同时这个isSorted()方法 是泛型方法  这个数组也是泛型数组
    // 并且为了进行有序比较 那么这个必须是可比较的 而实现可比较 就需要有泛型约束 就得实现 Comparable 接口 重复在提
    public static <E extends Comparable<E>> boolean isSorted(E[] arr) {
        for (int i = 1; i < arr.length; i++)
            // 为什么循环从 1 开始 是因为我每次要在循环中比较的是 arr[i-1]于arr[i] 的大小关系 也就是1 和2  2和3 依次推后的关系
            // 而使用了 Comparable接口就一定会使用到 compareTo这个方法 来进行比较
            if (arr[i - 1].compareTo(arr[i]) > 0) // 此处结果要是大于0 说明使用排序算法进行排序后的数组就不是有序的 也就是说结果不对
                return false;
            return true; // 要是没有提示 false错误 那就证明我们排序后的数组是对的是有序的
    }
}

辅助判断方法封装完成 ,现在去测试调用 将方法在报告测试算法时间性能之前 我们就进行结果的验证

SelectionSort_05 .java

package src;
/**
 * @author xxz
 * @version 1.0
 * @Created on: 2024-01-17 14:50
 * @Description: 优化的排序算法 既有排序算法也有对排序算法的结果验证 然后有算法时间性能的展示
 */
public class SelectionSort_05 {
    private SelectionSort_05(){}
    public static <E extends Comparable<E>> void sort (E [] arr){ //进行实现 Comparable 接口来实现泛型可以进行1比较
        // arr[0.....i) 是有序的; arr[i......n)是无序的
        for (int i = 0; i < arr.length; i++) {
            int minIndex = i ;
            // 选择 arr[i...n]中最小的索引
            for(int j = i; j<arr.length; j++){
                if (arr[j].compareTo(arr[minIndex])<0)
                    minIndex = j;
            }
            swap(arr, i ,minIndex);
        }
    }
    //修改  swap方法 为泛型方法
    private static <E> void swap(E [] arr, int i ,int j){
        E t  = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }
      // 测试 1万数据量
      public static void main(String[] args) {
        // 设定测试数据最大量为1万
        int n = 10000;
          // 随机生成数组的参数1是最大容量和数组大小都设定为 1万    ArrayGenerator 类只是提供了随机生成数组的方法
        Integer[] arr = ArrayGenerator.generateRandomArray(n,n);
            // 为了记录算法对数据的排序耗时  在排序进行前和后进行记录时间戳
          long startTime = System.nanoTime(); // 开始时间
          // 使用上面的排序算法进行排序
          SelectionSort_05.sort(arr);
          long endTime = System.nanoTime();   // 结束时间

          //换算时间 time 来接收 结果
          double time =  (endTime - startTime) / 1000000000.0;


          // SortingHelper 调用isSorted()来验证结果是否有序 也就是排序算法是否有效 要是有效 我们计算算法时间性能有价值 要是无效 就数组都没排序 计算性能没用
          // 验证结果是否有效 要无效的话 我就抛出异常
          if (!SortingHelper.isSorted(arr))
            throw new RuntimeException("验证结果数组不是有序的,所以排序算法失效");
          System.out.println("测试1万条数据进行排序花费时间"+time+ " 秒");
      }
}

image-20240117145841407

测试出异常的 情况:

image-20240117151604200

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值