image.png

image.png
image.png
image.png
image.png

快排

  • 归并排序将数组分为两个子数组分别排序,并将有序的子数组归并使得整个数组排序;
  • 快速排序通过一个切分元素将数组分为两个子数组,左子数组小于等于切分元素,右子数组大于等于切分元素,
  • 将这两个子数组排序也就将整个数组排序了

JAVA排序 - 图7
https://www.bilibili.com/video/BV117411x72U?p=2
image.png
image.png

  1. package com.kuang.offer;
  2. public class quickSort {
  3. public static int[] arr = new int[]{3, 2, 6, 8, 9 , 10, 1,11,5,97,888};
  4. public static void main(String[] args) {
  5. quick(arr, 0, arr.length - 1);
  6. for(int i: arr){
  7. System.out.println(i);
  8. }
  9. }
  10. public static void quick(int[] arr, int left, int right){
  11. if(arr == null || arr.length == 0) return;
  12. if(left > right) return;
  13. int key = arr[left];
  14. int l = left;
  15. int r = right;
  16. while(l != r){
  17. while(arr[r] >= key && l < r) r--;
  18. while(arr[l] <= key && l < r) l++;
  19. if(l < r){
  20. int temp = arr[l];
  21. arr[l] = arr[r];
  22. arr[r] = temp;
  23. }
  24. }
  25. arr[left] = arr[l];
  26. arr[l] = key;
  27. quick(arr, left, l - 1);
  28. quick(arr, l+ 1, right);
  29. }
  30. }

arr[left] = arr[l] arr[l] = key 基点和中间值交换

image.png

冒泡

JAVA排序 - 图11

1.冒泡排序 a、冒泡排序,是通过每一次遍历获取最大/最小值 b、将最大值/最小值放在尾部/头部

c、然后除开最大值/最小值,剩下的数据在进行遍历获取最大/最小值

d、代码实现

image.png

  1. package com.kuang.offer;
  2. public class bubble {
  3. public static void main(String[] args) {
  4. int[] nums = {8, 5, 3, 2, 4};
  5. for (int num : nums) {
  6. System.out.println(num);
  7. }
  8. }
  9. public static void bubble_(int[] arr){
  10. for(int i = 0; i< arr.length - 1; i++){
  11. for(int j = 0; j < arr.length - i - 1; i++){
  12. if(arr[j] > arr[j + 1]){
  13. int temp = arr[j + 1];
  14. arr[j + 1] = arr[j];
  15. arr[j] = temp;
  16. }
  17. }
  18. }
  19. }
  20. }

选择排序

a、将第一个值看成最小值 b、然后和后续的比较找出最小值和下标 c、交换本次遍历的起始值和最小值 d、说明:每次遍历的时候,将前面找出的最小值,看成一个有序的列表,后面的看成无序的列 表,然后每次遍历无序列表找出最小值。

JAVA排序 - 图13
image.png

  1. package com.kuang.offer;
  2. public class select {
  3. public static void main(String[] args) {
  4. int[] arr = {6, 5, 4, 3, 8};
  5. for(int i = 0; i < arr.length; i++){
  6. //默认第一个是最小的
  7. int min = arr[i];
  8. //记录最小的下标
  9. int index = i;
  10. //通过与后面的数据进行比较得出,最小值下标
  11. for(int j = i + 1; j < arr.length; j++){
  12. if(min > arr[j]){
  13. min = arr[j];
  14. index = j;
  15. }
  16. }
  17. //然后将最小值与本次循环的,开始值交换
  18. int temp = arr[i];
  19. arr[i] = min;
  20. arr[index] = temp; //将i前面的数据看成一个排好的队列,i后面的看成是一个无序队列,
  21. // 每次只需要找到无序的最小值,做替换
  22. }
  23. for (int i: arr) {
  24. System.out.println(i);
  25. }
  26. }
  27. }

插入排序

a、默认从第二个数据开始比较。 b、如果第二个数据比第一个小,则交换。然后在用第三个数据比较,如果比前面小,则插入(狡 猾)。否则,退出循环 c、说明:默认将第一数据看成有序列表,后面无序的列表循环每一个数据,如果比前面的数据小 则插入(交换)。否则退出。

JAVA排序 - 图15
image.png

  1. package com.kuang.offer;
  2. public class insert {
  3. public static void main(String[] args) {
  4. int[] arr = {7, 5, 3, 2, 4};
  5. //外层循环,从第二个开始比较
  6. for(int i = 1; i < arr.length; i++){
  7. //内层循环,与前面拍好序的数据比较,如果后面的数据小于前面的则交换
  8. for(int j = i; j > 0; j--){
  9. if(arr[j] < arr[j - 1]){
  10. int temp = arr[j - 1];
  11. arr[j - 1] = arr[j];
  12. arr[j] = temp;
  13. }else{
  14. //如果不小于,说明插入完毕,退出内层循环
  15. break;
  16. }
  17. }
  18. }
  19. for(int i: arr){
  20. System.out.println(i);
  21. }
  22. }
  23. }

希尔排序(插入排序变种版)

a、基本上和插入排序一样的道理 b、不一样的地方在于,每次循环的步长,通过减半的方式来实现 c、说明:基本原理和插入排序类似,不一样的地方在于。通过间隔多个数据来进行插入排序。

image.png

  1. package com.kuang.offer;
  2. public class xshell {
  3. public static void main(String[] args) {
  4. int[] arr = {7, 5, 3, 2, 1};
  5. //i层循环控制步长
  6. for(int i = arr.length / 2; i > 0; i /= 2){
  7. //j控制无序端的起始位置
  8. for(int j = i; j < arr.length; j++){
  9. for(int k = j; k > 0 && k - i >= 0; k -= i){
  10. if(arr[k] < arr[k - i]){
  11. int temp = arr[k - i];
  12. arr[k - i] = arr[k];
  13. arr[k] = temp;
  14. }else{
  15. break;
  16. }
  17. }
  18. }
  19. } //j, k为插入排序,不过步长为i
  20. for(int i : arr){
  21. System.out.println(i);
  22. }
  23. }
  24. }

归并排序

image.png
image.png
image.png
image.png

  1. package com.kuang.offer;
  2. import java.util.Arrays;
  3. public class MergeSort {
  4. public static void main(String[] args) {
  5. int arr[] = {7, 5, 3, 2, 4, 1, 6};
  6. //归并排序
  7. int start = 0;
  8. int end = arr.length - 1;
  9. mergeSort(arr, start, end);
  10. for (int i : arr){
  11. System.out.println(i);
  12. }
  13. }
  14. public static void mergeSort(int[] arr, int start, int end) {
  15. //判断拆分的不为最小单位
  16. if (end - start > 0) {
  17. //再一次拆分,知道拆成一个一个的数据
  18. mergeSort(arr, start, (start + end) / 2);
  19. mergeSort(arr, (start + end) / 2 + 1, end);
  20. //记录开始/结束位置
  21. int left = start;
  22. int right = (start + end) / 2 + 1;
  23. //记录每个小单位的排序结果
  24. int index = 0;
  25. int[] result = new int[end - start + 1];
  26. //如果查分后的两块数据,都还存在
  27. while (left <= (start + end) / 2 && right <= end) {
  28. //比较两块数据的大小,然后赋值,并且移动下标
  29. if (arr[left] <= arr[right]) {
  30. result[index] = arr[left];
  31. left++;
  32. } else {
  33. result[index] = arr[right];
  34. right++;
  35. }
  36. //移动单位记录的下标
  37. index++;
  38. }
  39. //当某一块数据不存在了时
  40. while (left <= (start + end) / 2 || right <= end) {
  41. //直接赋值到记录下标
  42. if (left <= (start + end) / 2) {
  43. result[index] = arr[left];
  44. left++;
  45. } else {
  46. result[index] = arr[right];
  47. right++;
  48. }
  49. index++;
  50. }
  51. //最后将新的数据赋值给原来的列表,并且是对应分块后的下标。
  52. for (int i = start; i <= end; i++) {
  53. arr[i] = result[i - start];
  54. }
  55. }
  56. }
  57. }

归并排序(精简版)

image.png
image.png
image.png
image.png
image.png
image.png
image.png

  1. package sortdemo;
  2. import java.util.Arrays;
  3. public class MergeSort {
  4. public static void main(String []args){
  5. int []arr = {9,8,7,6,5,4,3,2,1};
  6. sort(arr);
  7. System.out.println(Arrays.toString(arr));
  8. }
  9. public static void sort(int []arr){
  10. int []temp = new int[arr.length];//在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间
  11. sort(arr,0,arr.length-1,temp);
  12. }
  13. private static void sort(int[] arr,int left,int right,int []temp){
  14. if(left<right){
  15. int mid = (left+right)/2;
  16. sort(arr,left,mid,temp);//左边归并排序,使得左子序列有序
  17. sort(arr,mid+1,right,temp);//右边归并排序,使得右子序列有序
  18. merge(arr,left,mid,right,temp);//将两个有序子数组合并操作
  19. }
  20. }
  21. private static void merge(int[] arr,int left,int mid,int right,int[] temp){
  22. int i = left;//左序列指针
  23. int j = mid+1;//右序列指针
  24. int t = 0;//临时数组指针
  25. while (i<=mid && j<=right){
  26. if(arr[i]<=arr[j]){
  27. temp[t++] = arr[i++];
  28. }else {
  29. temp[t++] = arr[j++];
  30. }
  31. }
  32. while(i<=mid){//将左边剩余元素填充进temp中
  33. temp[t++] = arr[i++];
  34. }
  35. while(j<=right){//将右序列剩余元素填充进temp中
  36. temp[t++] = arr[j++];
  37. }
  38. t = 0;
  39. //将temp中的元素全部拷贝到原数组中
  40. while(left <= right){
  41. arr[left++] = temp[t++];
  42. }
  43. }
  44. }

image.png