类别 | 排序方法 | 时间复杂度 | 空间复杂度 | 排序方式 | 稳定性 | ||
平均时间复杂度 | 最好情况 | 最坏情况 | |||||
交换排序 | 冒泡排序 | In-place | 稳定 | ||||
快速排序 | In-place | 不稳定 |
package com.my.sort;
public interface IArraySort {
public int[] sort(int[] sourceArray);
}
要排序数组:int[] arr = {7, 2, 6, 5, 9, 4};
第1轮排序前数组为:[7, 2, 6, 5, 9, 4]
第1轮第1次比较:7大于2交换位置:[2, 7, 6, 5, 9, 4]
第1轮第2次比较:7大于6交换位置:[2, 6, 7, 5, 9, 4]
第1轮第3次比较:7大于5交换位置:[2, 6, 5, 7, 9, 4]
第1轮第4次比较:7小于9不交换位置:[2, 6, 5, 7, 9, 4]
第1轮第5次比较:9大于4交换位置:[2, 6, 5, 7, 4, 9]
第1轮排序后数组为:[2, 6, 5, 7, 4, 9]
第2轮排序前数组为:[2, 6, 5, 7, 4, 9]
第2轮第1次比较:2小于6不交换位置:[2, 6, 5, 7, 4, 9]
第2轮第2次比较:6大于5交换位置:[2, 5, 6, 7, 4, 9]
第2轮第3次比较:6小于7不交换位置:[2, 5, 6, 7, 4, 9]
第2轮第4次比较:7大于4交换位置:[2, 5, 6, 4, 7, 9]
第2轮排序后数组为:[2, 5, 6, 4, 7, 9]
第3轮排序前数组为:[2, 5, 6, 4, 7, 9]
第3轮第1次比较:2小于5不交换位置:[2, 5, 6, 4, 7, 9]
第3轮第2次比较:5小于6不交换位置:[2, 5, 6, 4, 7, 9]
第3轮第3次比较:6大于4交换位置:[2, 5, 4, 6, 7, 9]
第3轮排序后数组为:[2, 5, 4, 6, 7, 9]
第4轮排序前数组为:[2, 5, 4, 6, 7, 9]
第4轮第1次比较:2小于5不交换位置:[2, 5, 4, 6, 7, 9]
第4轮第2次比较:5大于4交换位置:[2, 4, 5, 6, 7, 9]
第4轮排序后数组为:[2, 4, 5, 6, 7, 9]
第5轮排序前数组为:[2, 4, 5, 6, 7, 9]
第5轮第1次比较:2小于4不交换位置:[2, 4, 5, 6, 7, 9]
第5轮排序后数组为:[2, 4, 5, 6, 7, 9]
已排序后的数组为:[2, 4, 5, 6, 7, 9]
由此可见:N个数字要完成排序,总共要进行N-1轮排序,每i轮的排序次数为(N-i)次,所以可以用双重循环语句,外层控制循环多少趟,内层控制每一趟的循环次数,即
for(int i = 0; i < arr.length - 1; i++){
for(int j = 0; j < arr.length - (i + 1); j++){
//交换位置
}
}
package com.my.sort;
import java.util.Arrays;
public class Client {
public static void main(String[] args) {
int[] sourceArray = {7,2,6,5,9,4};
BubbleSort bSort = new BubbleSort();
System.out.println(Arrays.toString(sourceArray));
int[] arr = bSort.sort(sourceArray);
System.out.println(Arrays.toString(arr));
}
}
package com.my.sort;
import java.util.Arrays;
public class BubbleSort implements IArraySort {
@Override
public int[] sort(int[] sourceArray) {
//对arr进行拷贝,不改变参数内容
int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
for(int i = 0; i < arr.length - 1; i++) {
//设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已经完成
boolean flag = true;
for(int j = 0; j < arr.length - (1 + i); j++) {
if(arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
flag = false;
}
}
if(flag) {
break;
}
}
return arr;
}
}
[7, 2, 6, 5, 9, 4]
[2, 4, 5, 6, 7, 9]
要排序数组:int[] arr = {7, 2, 6, 5, 9, 4};
下标:0 1 2 3 4 5
元素:7 2 6 5 9 4
假设7为基准值,pivot = 0
i = 1,j = 1:arr[j] < arr[pivot],交换 arr[i] 和 arr[j] 后,数组为:[7,2,6,5,9,4] i++ , j++
i = 2,j = 2:arr[j] < arr[pivot],交换 arr[i] 和 arr[j] 后,数组为:[7,2,6,5,9,4] i++ , j++
i = 3,j = 3:arr[j] < arr[pivot],交换 arr[i] 和 arr[j] 后,数组为:[7,2,6,5,9,4] i++ , j++
i = 4,j = 4:arr[j] > arr[pivot],交换 arr[i] 和 arr[j] 后,数组为:[7,2,6,5,9,4] j++
i = 4,j = 5:arr[j] < arr[pivot],交换 arr[i] 和 arr[j] 后,数组为:[7,2,6,5,4,9] i++ , j++
i = 5,j = 6
一轮交换结束,交换 pivot 和 i - 1所指向的值后,数组为:[4,2,6,5,7,9]
pivot = 4 arr[pivot] = 7
元素:{4 2 6 5} {7} { 9 }
pivot = 4 arr[pivot] = 7
pivot 右边只有一个元素,不用排序
对 pivot 左边的元素进行快速排序
下标:0 1 2 3
pivot 左边元素:4 2 6 5
假设4为新的基准值,pivot = 0
i = 1,j = 1:arr[j] < arr[pivot],交换 arr[i] 和 arr[j] 后,数组为:[4,2,6,5] i++ , j++
i = 2,j = 2:arr[j] > arr[pivot],交换 arr[i] 和 arr[j] 后,数组为:[4,2,6,5] j++
i = 2,j = 3:arr[j] > arr[pivot],交换 arr[i] 和 arr[j] 后,数组为:[4,2,5,6] j++
i = 2,j = 4
一轮交换结束,交换 pivot 和 i - 1所指向的值后,数组为:[2,4,5,6]
pivot = 1 arr[pivot] = 4
元素:{2 4 5 6} {7} {9}
元素:{2} {4} {5 6}
pivot = 1 arr[pivot] = 4
pivot 左边只有一个元素,不用排序
对 pivot 右边的元素进行快速排序
下标:0 1
pivot 右边元素:5 6
假设5为新的基准值,pivot = 0
i = 1,j = 1:arr[j] > arr[pivot],交换 arr[i] 和 arr[j] 后,数组为:[5,6] j++
i = 1,j = 2
一轮交换结束,交换 pivot 和 i - 1所指向的值后,数组为:[5,6]
元素:{2} {4} {5 6}
第一次合并左右数组后,数组为:[2,4,5,6,]
第二次合并左右数组后,数组为:[2,4,5,6,7,9]
已排序后的数组为:[2, 4, 5, 6, 7, 9]
package com.my.sort;
import java.util.Arrays;
public class Client {
public static void main(String[] args) {
int[] sourceArray = {7,2,6,5,9,4};
QuickSort qSort = new QuickSort();
System.out.println(Arrays.toString(sourceArray));
int[] arr = qSort.sort(sourceArray);
System.out.println(Arrays.toString(arr));
}
}
package com.my.sort;
import java.util.Arrays;
public class QuickSort implements IArraySort {
@Override
public int[] sort(int[] sourceArray) {
//对arr进行拷贝,不改变参数内容
int[] arr = Arrays.copyOf(sourceArray,sourceArray.length);
//返回快速排序后的数组
return quickSort(arr,0,arr.length - 1);
}
private int[] quickSort(int[] arr,int left,int right) {
if(left < right) {
//partitionIndex用来记录基准值的下标,partition方法用来找到基准值的下标
int partitionIndex = partition(arr,left,right);
//对基准值左侧的元素进行快速排序
quickSort(arr,left,partitionIndex - 1);
//对基准值右侧的元素进行快速排序
quickSort(arr,partitionIndex + 1,right);
}
//返回排序好的数组
return arr;
}
//找到基准值并返回其下标
private int partition(int[] arr,int left,int right) {
//设置基准值(pivot)
int pivot = left;
int index = pivot + 1;
for(int i = index; i <= right; i++) {
if(arr[i] < arr[pivot]) {
swap(arr,i,index);
index++;
}
}
swap(arr,pivot,index - 1);
return index - 1;
}
//交换指定数组的两个指定元素的值
private void swap(int[] arr,int i,int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
[7, 2, 6, 5, 9, 4]
[2, 4, 5, 6, 7, 9]