0
点赞
收藏
分享

微信扫一扫

SolidWorks二次开发系列入门100篇之98、99-分割、保存零件中的实体

君之言之 2023-08-08 阅读 22

基本思想

在这里插入图片描述

  1. 从序列的第一个元素开始,比较相邻的两个元素大小,如果它们的顺序不正确,则交换它们的位置。
  2. 继续向后遍历序列,对每一对相邻元素执行步骤1,直到序列的末尾。
  3. 重复上述过程,但是每次比较的元素个数减一,因为每次遍历都会将最大(或最小)的元素“冒泡”到正确的位置。
  4. 重复执行以上步骤,直到整个序列排序完成。

代码实现

对应在代码层面,就是两轮for循环来进行遍历,这种思想还是比较简单且容易理解的(简单粗暴)

/**
 * @author HelloCode
 * @blog https://www.hellocode.top
 * @date 2023年08月07日 20:43
 */
public static void bubbleSort(int[] arr){
    for(int i = 0; i < arr.length; i++){
        for (int j = 0; j < arr.length - i - 1; j++){
            if(arr[j] > arr[j + 1]){
                // 需要交换
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

测试:

/**
 * @author HelloCode
 * @blog https://www.hellocode.top
 * @date 2023年08月07日 20:43
 */
public class Test {
    public static void main(String[] args) {
        int[] arr = {21, 13, 4, 10, 7, 65, 32, 15, 32, 19};
        System.out.println("排序前:" + Arrays.toString(arr));
        BubbleSort.bubbleSort(arr);
        System.out.println("排序后:" + Arrays.toString(arr));
    }
}

在这里插入图片描述

优化

优化法一

在每一轮循环之前,设置一个标志位来标记本轮循环是否进行了元素交换。如果在一轮循环中没有发生任何交换操作,说明整个数组已经有序,就无需继续进行后续的比较,直接退出循环。这个优化可以提前结束排序过程,减少了不必要的比较操作,从而提高算法的效率。然而,当数组内的元素乱序程度较高时,这种优化的效果可能并不明显。具体代码如下:

/**
 * @author HelloCode
 * @blog https://www.hellocode.top
 * @date 2023年08月07日 21:00
 */
public static void bubbleSortOptimized1(int[] arr) {
    for (int i = 0; i < arr.length; i++) {
        boolean isSwap = false;
        for (int j = 0; j < arr.length - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                // 需要交换,设置标记位为true
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
                isSwap = true;
            }
        }
        if (!isSwap) {
            // 如果一轮循环结束未发生一次交换,则说明已经有序,提前结束循环
            break;
        }
    }
}

测试:

/**
 * @author HelloCode
 * @blog https://www.hellocode.top
 * @date 2023年08月07日 21:02
 */
public class Test {
    public static void main(String[] args) {
        int[] arr = {21, 13, 4, 10, 7, 65, 32, 15, 32, 19};
        System.out.println("排序前:" + Arrays.toString(arr));
        BubbleSort.bubbleSortOptimized1(arr);
        System.out.println("排序后:" + Arrays.toString(arr));
    }
}

在这里插入图片描述

优化法二

在外层和内层两个循环中,内层循环进行两次遍历:一次从头到尾,找出本轮循环中最大的元素;另一次从尾到头,找出本轮循环中最小的元素。结合优化法一使用标志位提前退出循环的方式,可以进一步减少每轮循环中的比较次数,从而提高冒泡排序的性能。具体代码如下:

/**
 * @author HelloCode
 * @blog https://www.hellocode.top
 * @date 2023年08月07日 21:10
 */

public static void bubbleSortOptimized2(int[] arr) {
    for (int i = 0; i < arr.length; i++) {
        boolean isSwap = false;
        // 从头到尾找出最大元素并将其冒泡到正确位置
        for (int j = 0; j < arr.length - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                // 需要交换,设置标记位为true
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
                isSwap = true;
            }
        }
        if (!isSwap) {
            // 如果一轮循环结束未发生一次交换,则说明已经有序,提前结束循环
            break;
        }
        isSwap = false;
        // 从尾到头找出最小元素并将其冒泡到正确位置
        for (int j = arr.length - i - 2; j >= i + 1; j--) {
            if (arr[j] < arr[j - 1]) {
                // 需要交换,设置标记位为true
                int temp = arr[j];
                arr[j] = arr[j - 1];
                arr[j - 1] = temp;
                isSwap = true;
            }
        }
        if (!isSwap) {
            // 如果一轮循环结束未发生一次交换,则说明已经有序,提前结束循环
            break;
        }
    }
}

测试:

/**
 * @author HelloCode
 * @blog https://www.hellocode.top
 * @date 2023年08月07日 21:18
 */
public class Test {
    public static void main(String[] args) {
        int[] arr = {21, 13, 4, 10, 7, 65, 32, 15, 32, 19};
        System.out.println("排序前:" + Arrays.toString(arr));
        BubbleSort.bubbleSortOptimized2(arr);
        System.out.println("排序后:" + Arrays.toString(arr));
    }
}

在这里插入图片描述

总结

优点

  1. 冒泡排序算法实现简单,易于理解和实现。
  2. 对于小规模的数据集,冒泡排序可能比其他排序算法性能稍微好一些。
  3. 由于每次只交换相邻元素,冒泡排序可以实现原地排序,不需要额外的内存空间。

缺点

  1. 冒泡排序的时间复杂度较高,特别是对于大规模数据集。它需要进行多次遍历和交换操作,导致性能较差。
  2. 不管数据集是否已经有序,冒泡排序都要执行完所有的遍历和比较操作。

复杂度

  • 时间复杂度:冒泡排序的最坏时间复杂度为O(n2),平均时间复杂度也为O(n2),其中n为待排序序列的长度。在最好情况下(待排序序列已经有序),冒泡排序的时间复杂度为O(n)。
  • 空间复杂度:冒泡排序是一种原地排序算法,不需要额外的内存空间,因此空间复杂度为O(1)。
举报

相关推荐

0 条评论