交换类排序主要是通过两两比较待排元素的关键字,若发现与排序要求相逆,则“交换”之。在这类排序方法中最常见的是冒泡排序和快速排序。简单写一写冒泡排序。
冒泡排序的思想
首先,将 n 个元素中的第一个元素和第二个元素进行比较,如果两个元素的位置为逆序,则交换两个元素的位置;进而比较第二个和第三个元素关键字,如此类推,直到比较第 n-1 个元素和第 n 个元素为止;上述过程描述了冒泡排序的第一趟排序过程,在第一趟排序过程中,我们将关键字最大的元素通过交换操作放到了具有 n 个元素的序列的最后一个位置上。然后进行第二趟排序,在第二趟排序过程中对元素序列的前 n-1 个元素进行相同操作,其结果是将关键字次大的元素通过交换放到第 n-1 个位置上。一般来说,第 i (i>=1)趟排序是对元素序列的前 n-i+1 个元素进行排序,使得前 n-i+1 个元素中关键字最大的元素被放置到第 n-i+1 个位置上。排序共进行 n-1 趟,即可使得元素序列按关键字有序。
代码实现
public class BubbleSortTest {
public static void main(String[] args) {
Integer[] arr = {5,2,7,3,9,10,8,6,1,4};
bubbleSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void bubbleSort(Integer[] arr){
//假设从小到大排序
//此标志是:如果在第一趟排序时没有交换任何元素位置,那么就说明该数组是有序的。
boolean flag = false;
//外层循环是第几趟排序过程,最后只剩一个元素的时候就不需要比较了。
//所以,对于长度为n的数组,需要进行n-1趟排序
for (int i = 1; i < arr.length; i++) {
//在每一趟排序后,数组右侧有序区逐渐变大,在第i趟排序要对数组的前n-i+1个元素进行排序,
//第n-i+1个元素的索引是n-i,同时,需要保证j+1<=n-i
for (int j = 0; j < arr.length-i; j++) {
if (arr[j] > arr[j+1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
flag = true;
}
}
if(!flag) {break;}
}
}
}
如果还是不理解这两个for循环i和j的取值范围,可以自己在纸上画一画。
空间效率
仅使用一个辅助存储单元。
时间效率
冒泡排序的时间复杂度为Ο(n2)【n的平方】。