1、冒泡排序

冒泡排序是知名排序方式,逻辑简单,实现起来也容易;
总的来说就是两层for循环,缺点就是时间复杂度较高。
一共进行n-1次循环,总比较次数:(n-1)+(n-2)+(n-3)……2+1=n*(n-1)/2,时间复杂度为O(n²)。
代码如下:

  1. public class BubbleSort {
  2. public static void main(String[] args) {
  3. int[] arr = {12, 45, 5677, 344, 56, 3, 546, 2435};
  4. //冒泡排序
  5. int[] bubbleSort = bubbleSort(arr);
  6. System.out.println(Arrays.toString(bubbleSort));
  7. }
  8. /**
  9. * 冒泡排序
  10. *
  11. * @param arr
  12. */
  13. public static int[] bubbleSort(int[] arr) {
  14. //i控制循环次数,长度为len的数组只需要循环len-1次,i的起始值为0所以i<len-1
  15. for (int i = 0; i < arr.length - 1; i++) {
  16. //但是由于是由arr[j]跟arr[j+1]进行比较,所以为了保证arr[j+1]不越界,j<len-i-1
  17. for (int l = 0; l < arr.length - i - 1; l++) {
  18. if (arr[l] > arr[l + 1]) {
  19. //交换两个数,//如果前一个数比后一个数大,则交换位置将大的数往后放。
  20. arr[l + 1] = arr[l + 1] ^ arr[l];
  21. arr[l] = arr[l + 1] ^ arr[l];
  22. arr[l + 1] = arr[l + 1] ^ arr[l];
  23. }
  24. }
  25. }
  26. return arr;
  27. }

2、选择排序

选择排序是比冒泡更为快速的排序方式,时间复杂度有所降低,实现思路如下:

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

实现代码如下:

  1. /**
  2. * 选择排序
  3. *
  4. * @return
  5. */
  6. public static int[] selectSort(int[] arr) {
  7. //第一次循环数组
  8. for (int i = 0; i < arr.length - 1; i++) {
  9. //定义最小数下标
  10. int miniIndex = i;
  11. //第二次循环数组
  12. for (int l = i + 1; l < arr.length; l++) {
  13. //碰到比最小值小的,重新标记最小标
  14. if (arr[l] < arr[miniIndex]) {
  15. miniIndex = l;
  16. }
  17. }
  18. //交换下标对于数值
  19. if (miniIndex != i) {
  20. arr[miniIndex] = arr[miniIndex] ^ arr[i];
  21. arr[i] = arr[miniIndex] ^ arr[i];
  22. arr[miniIndex] = arr[miniIndex] ^ arr[i];
  23. }
  24. }
  25. return arr;
  26. }

3、归并排序

归并排序体现了分治思想,把排序对象分割成两个,在进行比对大小,思路如下:

  • 将列表按照对等的方式进行拆分
  • 拆分小最小快的时候,在将最小块按照原来的拆分,进行合并
  • 合并的时候,通过左右两块的左边开始比较大小。小的数据放入新的块中
  • 说明:简单一点就是先对半拆成最小单位,然后将两半数据合并成一个有序的列表。

代码实现如下:

  1. /**
  2. * 归并排序
  3. *
  4. * @return
  5. */
  6. public static int[] mergeSort(int[] arr) {
  7. if (arr.length<=1) {
  8. return arr;
  9. }
  10. //得到数组长度中值
  11. int num = arr.length >> 1;
  12. int[] left = Arrays.copyOfRange(arr, 0, num);
  13. int[] right = Arrays.copyOfRange(arr, num, arr.length);
  14. //合并方法,递归
  15. return merge(mergeSort(left), mergeSort(right));
  16. }
  17. //归并排序合并方法
  18. private static int[] merge(int[] a, int[] b) {
  19. int i = 0, j = 0, k = 0;
  20. int[] result = new int[a.length + b.length];
  21. while (i < a.length && j < b.length) {
  22. if (a[i] <= b[j]) {
  23. result[k++] = a[i++];
  24. } else {
  25. result[k++] = b[j++];
  26. }
  27. }
  28. while (i < a.length) {
  29. result[k++] = a[i++];
  30. }
  31. while (j < b.length) {
  32. result[k++] = b[j++];
  33. }
  34. return result;
  35. }

4、快速排序

快速排序是最近面试常考排序方法,建议多练习;
快速排序也体现了分治思想,思路如下:

  • 选择基点的值(随意,建议去下标中值)
  • 将比基点值小的值放在左边,比基点值大的放在右边,这样基点左边都是比基点小的,右边都是比基点大的
  • 分别对左右两边进行递归运算

代码如下:

  1. import java.util.Arrays;
  2. /**
  3. * 快速排序
  4. */
  5. public class QuickSort {
  6. public static void main(String[] args) {
  7. int[] arr = {14, 25, 255, 7, 6, 89, 52, -5, 58, -88, -9, 5845, 4};
  8. quickSort(arr, 0, arr.length - 1);
  9. System.out.println("arr:" + Arrays.toString(arr));
  10. }
  11. /**
  12. * 排序方法
  13. *
  14. * @param arr 数组
  15. * @param left 左下标
  16. * @param right 右下标
  17. */
  18. private static void quickSort(int[] arr, int left, int right) {
  19. int l = left;
  20. int r = right;
  21. int pivot = arr[(left + right) / 2];
  22. int temp = 0;
  23. while (l < r) {
  24. //找到左边大于等于pivot的值下标
  25. while (arr[l] < pivot) {
  26. l += 1;
  27. }
  28. //找到右边小于等于pivot的值下标
  29. while (arr[r] > pivot) {
  30. r -= 1;
  31. }
  32. if (l >= r) {
  33. break;
  34. }
  35. //交换值
  36. temp = arr[l];
  37. arr[l] = arr[r];
  38. arr[r] = temp;
  39. //如果交换完成后,发现arr[l]==pivot,r--,r左移一位
  40. if (arr[l] == pivot) {
  41. r -= 1;
  42. }
  43. //如果交换完成后,发现arr[l]==pivot,r--,r左移一位
  44. if (arr[r] == pivot) {
  45. l += 1;
  46. }
  47. //如果l==r,错开,否则造成栈溢出
  48. if (l == r) {
  49. l += 1;
  50. r -= 1;
  51. }
  52. //向左递归
  53. if (left < r) {
  54. quickSort(arr, left, r);
  55. }
  56. //向右递归
  57. if (right > l) {
  58. quickSort(arr, l, right);
  59. }
  60. }
  61. }
  62. }