冒泡排序(Bubble Sort)
1.实现过程
有6个数字待排序:a[0] = 4,a[1] =6,a[2] =5,a[3] =3,a[4] =2,a[5] =1
第一次排序:
a[5]<a[0]-->a[0] = 1,a[5] =4;
a[5]<a[1]-->a[1] = 4,a[5] =6;
a[5]>a[2]-->不处理;
a[5]>a[3]-->不处理;
a[5]>a[4]-->不处理;
a[0] = 1,a[1] =4;a[2] =5;a[3] =3;a[4] =2;a[5] =6
这一段保证a[5]为最大值
第二次排序:
a[4]<a[0]-->a[0] = 1,a[4] =2;
a[4]<a[1]-->a[1] = 2,a[4] =4;
a[4]<a[2]-->a[2] = 4,a[4] =5;
a[4]>a[3]-->不处理;
a[0] = 1;a[1] =2;a[2] =4;a[3] =3;a[4] =5;a[5] =6
这一段保证a[4]<a[5]
第三次排序:
a[3]>a[0]--不处理;
a[3]>a[1]-->不处理;
a[3]<a[2]-->a[2] = 3,a[4] =4;
a[0] = 1;a[1] =2;a[2] =3;a[3] =4;a[4] =5;a[5] =6
这一段保证a[3]<a[4]<a[5]
由此可知,若对n个数字进行冒泡排序,第一次要排n-1趟,第二次要排n-2趟,第n-1次要排1趟。时间复杂度:
2.代码示例
@ResponseBody
@ApiOperation("冒泡排序")
@PostMapping("/bubbleSort")
public int[] bubbleSort(@RequestBody int[] a) {
for (int i = a.length - 1; i > 0; i--) {
// 将a[0...i]中最大的数据放在末尾
for (int j = 0; j < i; j++) {
if (a[j] > a[j + 1]) {
int tmp = a[j];
a[j] = a[j + 1];
a[j + 1] = tmp;
}
}
}
return a;
}
@ResponseBody
@ApiOperation("冒泡排序改进版")
@PostMapping("/greatBubbleSort")
public int[] greatBubbleSort(@RequestBody int[] a) {
Boolean flag;
for (int i = a.length - 1; i > 0; i--) {
flag = Boolean.FALSE;
// 将a[0...i]中最大的数据放在末尾
for (int j = 0; j < i; j++) {
if (a[j] > a[j + 1]) {
int tmp = a[j];
a[j] = a[j + 1];
a[j + 1] = tmp;
flag = Boolean.TRUE;
}
}
if (Boolean.FALSE.equals(flag)) {
break;
}
}
return a;
}
快速排序(Quick Sort)
1.实现过程
- 从数列中挑出一个基准值。
- 将所有比基准值小的摆放在基准前面,所有比基准值大的摆在基准的后面(相同的数可以到任一边);在这个分区退出之后,该基准就处于数列的中间位置。
- 递归地把"基准值前面的子数列"和"基准值后面的子数列"进行排序。
有6个数字待排序:a[0] = 4;a[1] =6;a[2] =5;a[3] =3;a[4] =2;a[5] =1
基准值:a[0]=4
①从右往左找到比4小的值并交换位置 4>a[5] a[0]与a[5]交换
a[0] = 1;a[1] =6;a[2] =5;a[3] =3;a[4] =2;a[5] =4
②从左往右找到比4大的值并交换位置 a[1]>4 a[2]与a[5]交换
a[0] = 1;a[1] =4;a[2] =5;a[3] =3;a[4] =2;a[5] =6
③从右往左找到比4小的值并交换位置 a[4]<4 a[1]与a[4]交换
a[0] = 1;a[1] =3;a[2] =5;a[3] =2;a[4] =4;a[5] =6
④从左往右找到比4大的值并交换位置 a[4]>4 a[2]与a[4]交换
a[0] = 1;a[1] =3;a[2] =4;a[3] =2;a[4] =5;a[5] =6
⑤从右往左找到比4小的值并交换位置 a[3]<4 a[2]与a[3]交换
a[0] = 1;a[1] =3;a[2] =2;a[3] =4;a[4] =5;a[5] =6
⑤第一趟结束
由此可知,若对n个数字进行冒泡排序,快速排序的时间复杂度在最坏情况下是O(N2),平均的时间复杂度是O(N*lgN)。
2.代码示例
/**
* 快速排序: Java
*
* @author sx
* @date 2024/03/19
*/
@ResponseBody
@ApiOperation("快速排序")
@PostMapping("/quickSort")
public List<Integer> QuickSort(@RequestBody int[] a) {
log.info("before sort:");
List<Integer> listBefore = Arrays.stream(a).boxed().collect(Collectors.toList());
log.info(listBefore);
int[] sort = sort(a, 0, a.length - 1);
log.info("after sort:");
List<Integer> listAfter = Arrays.stream(sort).boxed().collect(Collectors.toList());
log.info(listAfter);
return listAfter;
}
public int[] sort(int[] a, int l, int r) {
/*
* 快速排序
*
* 参数说明:
* a -- 待排序的数组
* l -- 数组的左边界(例如,从起始位置开始排序,则l=0)
* r -- 数组的右边界(例如,排序截至到数组末尾,则r=a.length-1)
*/
if (l < r) {
int i, j, x;
i = l;
j = r;
//基准数
x = a[i];
while (i < j) {
// 从右向左找第一个小于x的数
while (a[j] > x) {
j--;
}
if (i < j) {
a[i++] = a[j];
}
// 从左向右找第一个大于x的数
while (i < j && a[i] < x) {
i++;
}
if (i < j) {
a[j--] = a[i];
}
}
a[i] = x;
sort(a, l, i - 1); /* 递归调用 */
sort(a, i + 1, r); /* 递归调用 */
}
return a;
}
插入排序(Insertion Sort)
1.实现过程
把n个待排序的元素看成为一个有序表和一个无序表。开始时有序表中只包含1个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,将它插入到有序表中的适当位置,使之成为新的有序表,重复n-1次可完成排序过程。
有6个数字待排序:a[0] = 4;a[1] =6;a[2] =5;a[3] =3;a[4] =2;a[5] =1
第一趟:
有序表:a[0] = 4;无序表:a[1] =6;a[2] =5;a[3] =3;a[4] =2;a[5] =1
①a[1]>a[0],有序表:a[0] = 4;a[1] =6 无序表:a[2] =5;a[3] =3;a[4] =2;a[5] =1
②a[2]<a[1],有序表:a[0] = 4;a[1] =5,a[2] =6 无序表:a[3] =3;a[4] =2;a[5] =1
a[1]>a[0],不改变
③a[3]<a[2],有序表:a[0] = 4;a[1] =5,a[2] =3,a[3] =6 无序表:a[4] =2;a[5] =1
a[2]<a[1],有序表:a[0] = 4;a[1] =3,a[2] =5,a[3] =6 无序表:a[4] =2;a[5] =1
a[1]<a[0],有序表:a[0] = 3;a[1] =4,a[2] =5,a[3] =6 无序表:a[4] =2;a[5] =1
④a[4]<a[3],有序表:a[0] = 3;a[1] =4,a[2] =5,a[3] =2,a[4] =6 无序表:a[5] =1
a[3]<a[2],有序表:a[0] = 3;a[1] =4,a[2] =2,a[3] =5,a[4] =6 无序表:a[5] =1
a[2]<a[1],有序表:a[0] = 3,a[1] =2,a[2] =4,a[3] =5,a[4] =6 无序表:a[5] =1
a[1]<a[0],有序表:a[0] =2,a[1] =3,a[2] =4,a[3] =5,a[4] =6 无序表:a[5] =1
⑤a[5]<a[4],有序表:a[0] = 2,a[1] =3,a[2] =4,a[3] =5,a[4] =1,a[5] =6
a[4]<a[3],有序表:a[0] = 2,a[1] =3,a[2] =4,a[3] =1,a[4] =5,a[5] =6
a[3]<a[2],有序表:a[0] = 2,a[1] =3,a[2] =1,a[3] =4,a[4] =5,a[5] =6
a[2]<a[1],有序表:a[0] = 2,a[1] =1,a[2] =3,a[3] =4,a[4] =5,a[5] =6
a[1]<a[0],有序表:a[0] = 1,a[1] =2,a[2] =3,a[3] =4,a[4] =5,a[5] =6
被排序的数列中有n个数。遍历一趟的时间复杂度是O(n),需要遍历 n-1次。因此,直接插入排序的时间复杂度是O(n^2)
2.代码示例
/**
* 插入排序
*
* @author sx
* @date 2024/03/19
*/
@ResponseBody
@ApiOperation("插入排序")
@PostMapping("/insertSort")
public List<Integer> InsertSort(@RequestBody int[] a) {
log.info("before sort:");
List<Integer> listBefore = Arrays.stream(a).boxed().collect(Collectors.toList());
log.info(listBefore);
//开始排序
int i, j, k;
for (i = 1; i < a.length; i++) {
//为a[i]在前面的a[0...i-1]有序区间中找一个合适的位置
for (j = i - 1; j >= 0; j--) {
if (a[j] < a[i]) {
break;
}
}
//如找到了一个合适的位置
if (j != i - 1) {
//将比a[i]大的数据向后移
int temp = a[i];
for (k = i - 1; k > j; k--) {
a[k + 1] = a[k];
}
//将a[i]放到正确位置上
a[k + 1] = temp;
}
}
log.info("after sort:");
List<Integer> listAfter = Arrays.stream(a).boxed().collect(Collectors.toList());
log.info(listAfter);
return listAfter;
}