【Java】5.0 冒泡排序

【排序】
排序技术主要取决于两个因素
1.程序执行时间的长度
2.执行程序所需的空间

【冒泡排序】
我们可以使用许多不同的算法进行排序,排序数组的一种方法是使用冒泡
冒泡算法的思路是将最大的元素放在数组的右侧(末端)

现在,如果我们想要利用冒泡对一个数组进行排序,则思路如下:
1.遍历数组中的所有元素
2.然后,我们将两个元素相互比较,并将两个值中较大的一个放在最右边的位置
3.每次比较,我们都只是将每个元素和它右侧的进行比较

具体实施:
1.将当前元素与其右侧的元素进行比较,如果左侧元素的值更大,那么我们需要交换两个变量的值/交换位置
2.将目标移向下一位数,并进行1的操作。直到我们到达了数组的最后一位数————此时我们完成了第一轮排序,最大的数一定位于数组最右侧
3.现在,我们返回到第一位数,并从重复上述过程。这次的结是:第二个最大的数字放置在数组的倒数第二个元素中,在这次的过程中,无需检查最后一个元素,因为该元素已被排序了
4.重复上面的步骤,直到所有数都被排序

对于冒泡排序的每次迭代,数组的有效大小都会减小,因为要排序的元素减少了一个

要完成N个数字的排序,总共进行N-1趟排序,每i趟的排序次数为(N-i)次

【冒泡:代码示例】
首先我们完成单次冒泡的代码

随后再次添加一次循环,以进行完整排序

而实际上,我们在每次循环后都排好了当次循环的最大数————也就是说我们没必要在每次都遍历全部数组,如之前所说,第i次只要N-i次排序
因此,最完整的冒泡应该是:

public static void bubbleSort(int[] a)  {
for (intpass = 1; i < a.length; i++) {
    for (int j = 0; j < a.length-pass; j++) {
    if (a[j] > a[j+1]) { 
        int temp = a[j]; 
        a[j] = a[j+1]; 
        a[j+1] = temp; 
        }
      }
    }
}

实质上只有数组元素超级多的时候,二者才有肉眼上的区别
总迭代次数:(n-1) + (n-2) + ... + 1 = n×(n-1)/2
设内循环(测试和交换)的1次迭代需要以常数c为边界的时间,则总时间: c×n×(n-1)/2 = O(n^2)

对于已排序的输入,冒泡排序仍需要O(n^2)进行排序,因为它不会检查输入是否已排序
因此,可以通过使用一个标记isSorted来改进它:

public static void bubbleSort2(int[] a) {
for (int i = 1; i < a.length; i++) {
  boolean isSorted = true; // 预设数组是排序好的,且在“每次大循环”预设
    for (int j = 0; j < a.length-i; j++) {
     if (a[j] > a[j+1]) { 
        // 如果在某一处发现了不符合“从小到大”的排序,那么就更换二者,并且把isSorted设为false
        int temp = a[j];  
        a[j] = a[j+1];     
        a[j+1] = temp;
        isSorted= false; //设为false,并且希望下一次的大排序是排序好的
      }
    }
     if (isSorted) return;   //如果第一次的遍历就发现数组是排序好的,那么就直接返回结果,不用进行下一步排序了
  }
}

这样的好处在于:如果某次(可能是第一次,也可能是第X次)进行遍历排序就发现了数组是排序好了的,那么就不进行接下来的排序,节省了许多时间,妙啊

posted @ 2021-04-25 19:39  RetenQ  阅读(59)  评论(0编辑  收藏  举报