1、冒泡排序

冒泡排序(Bubble Sort)

排序原理

  1. 比较相邻的元素。如果前一个元素比后一个元素大,就交换这两个元素的位置。
  2. 对相邻的每一对元素做同样的操作,从开始第一对元素到结尾最后一对元素,最终最后位置的元素就是最大值。

image.png

代码实现

  1. public class Bubble {
  2. public void sort(Comparable[] a) {
  3. int n = a.length;
  4. for (int i = 0; i < n - 1; i++) {
  5. for (int j = 0; j < j - n -1; j++) {
  6. if (greater(a[j],a[j + 1])) {
  7. exchange(a, j, j + 1);
  8. }
  9. }
  10. }
  11. }
  12. //比较元素v是否大于元素w
  13. private boolean greater(Comparable v, Comparable w) {
  14. return v.compareTo(w) > 0;
  15. }
  16. //数组元素i和j交换位置
  17. private void exchange(Comparable[] a, int i, int j) {
  18. Comparable temp;
  19. temp = a[i];
  20. a[i] = a[j];
  21. a[j] = temp;
  22. }
  23. }
  1. public class Bubble {
  2. private static void sort(int nums[]) {
  3. int n = nums.length;
  4. for (int i = 0; i < n - 1; i++) {
  5. for (int j = 0; j < n - 1 - i; j++) {
  6. if (nums[j] > nums[j + 1]) {
  7. int temp;
  8. temp = nums[j];
  9. nums[j] = nums[j + 1];
  10. nums[j + 1] = temp;
  11. }
  12. }
  13. }
  14. }
  15. public static void main(String[] args) {
  16. int[] arr = {1, 3, 2, 5, 7, 6};
  17. sort(arr);
  18. System.out.println(Arrays.toString(arr));
  19. }
  20. }

2、选择排序

排序原理

  1. 在每一次遍历的过程中,都假定第一个索引处的的元素为最小值。依次和其他位置的值进行比较,不断更新最小值所在的索引。
  2. 交换第一个索引处的值和最小值所在索引的值

image.png

代码实现

  1. public class Selection {
  2. public static void sort(Comparable[] a) {
  3. int n = a.length;
  4. for (int i = 0; i < n - 1; i++) {
  5. int minIndex = i;
  6. for (int j = i + 1; j < n; j++) {
  7. if(greater(a[minIndex],a[j])) {
  8. minIndex = j;
  9. }
  10. }
  11. exch(a, i, minIndex);
  12. }
  13. }
  14. private static boolean greater(Comparable v, Comparable w) {
  15. return v.compareTo(w) > 0;
  16. }
  17. private static void exch(Comparable[] a, int i, int j) {
  18. Comparable temp;
  19. temp = a[i];
  20. a[i] = a[j];
  21. a[j]= temp;
  22. }
  23. }

3、插入排序

排序原理

  1. 所有元素分为两组,已经排序的和未排序的
  2. 找到未排序组中的第一个元素,向已排序的组中插入、
  3. 倒序遍历已经排序的元素,依次和待插入的元素比较。

image.png

代码实现

  1. public class Insertion {
  2. public static void sort(Comparable[] a) {
  3. int n = a.length;
  4. for (int i = 1; i < n; i++) {
  5. for (int j =i; j >= 0; j--) {
  6. if (greater(a[j - 1],a[j])) {
  7. exch(a, j - 1, j);
  8. } else {
  9. break;
  10. }
  11. }
  12. }
  13. }
  14. private static boolean greater(Comparable v, Comparable w) {
  15. return v.compareTo(w) > 0;
  16. }
  17. private static void exch(Comparable[] a, int i, int j) {
  18. Comparable temp;
  19. temp = a[i];
  20. a[i] = a[j];
  21. a[j] = temp;
  22. }
  23. }

希尔排序

希尔排序是插入排序的一种,又称“缩小增量排序”,是插入排序算法的一种更高效的改进版本。
如果已排序分组的元素是{2,5,7,9,10},未排序分组元素为{1,8},那么下一个待插入元素为1,我们需要拿着1进行倒序遍历(从后往前依次和10,9,7,5,2进行交换位置)。每次交换只能和相邻的元素进行。想要提高效率,直观的想法是交换一次,把1放到2之前,减少交换的次数。

排序原理

  1. 选定一个增长量h,按照h作为数据分组的依据来分组(一对数据)
  2. 对分好组的每一组数据进行插入排序
  3. 减小增长量,最小减为1,重复第二步操作

image.png

代码实现

  1. public class Shell {
  2. public static void sort(Comparable[] a) {
  3. //根据数组a的长度,确定增量h
  4. int h = 1;
  5. while (h < a.length / 2) {
  6. h = h * 2 + 1;
  7. }
  8. //希尔排序
  9. while (h >= 1) {
  10. //找到待插入的元素
  11. for (int i = h; i < a.length; i++) {
  12. for (int j = i; j >= h; j -= h) {
  13. if (greater(a[j - h], a[j])) {
  14. exch(a, j - h, j);
  15. } else {
  16. break;
  17. }
  18. }
  19. }
  20. h = h /2;
  21. }
  22. }
  23. private static boolean greater(Comparable v, Comparable w) {
  24. return v.compareTo(w) > 0;
  25. }
  26. private static void exch(Comparable[] a, int i, int j) {
  27. Comparable temp;
  28. temp = a[i];
  29. a[i] = a[j];
  30. a[j] = temp;
  31. }
  32. }

归并排序

排序原理

  1. 尽可能的将一组数据拆分成两个元素相等的子组,并对每一个子组继续拆分,直到拆分后的每个子组的元素个数为1
  2. 将相邻的两个子组进行合并,成为一个有序的大组
  3. 不断地重复步骤2,直到最终只有一个组

image.png

image.png

代码实现

  1. public class Merge {
  2. //所需要的辅助数组
  3. private static Comparable[] assist;
  4. //比较v元素是否小于w元素
  5. private static boolean less(Comparable v, Comparable w) {
  6. return v.compareTo(w) < 0;
  7. }
  8. //数组元素i和j交换位置
  9. private static void exch(Comparable[] a, int i, int j) {
  10. Comparable temp = a[i];
  11. a[i] = a[j];
  12. a[j] = temp;
  13. }
  14. //对数组a中的元素进行排序
  15. public static void sort(Comparable[] a) {
  16. //1.初始化辅助数组assit
  17. assist = new Comparable[a.length];
  18. //2.定义一个low变量和一个high变量,记录最小索引和最大索引
  19. int low = 0;
  20. int high = a.length - 1;
  21. //3.调用sort重载方法,完成从low到high索引的排序
  22. sort(a, low, high);
  23. }
  24. //对数组a中从low到high的元素进行排序
  25. public static void sort(Comparable[] a, int low, int high) {
  26. if (high <= low) {
  27. return;
  28. }
  29. //对low到high之间的数据进行分组,两个组
  30. int mid = low + (high - low) / 2;
  31. //分别对每一组数据进行排序
  32. sort(a, low, mid);
  33. sort(a,mid + 1,high);
  34. //再把两个数组中的数据进行归并
  35. merge(a, low, mid, high);
  36. }
  37. //对数组中,从low到mid为一组,从mid+1到high为一组,对着两组数据进行归并
  38. private static void merge(Comparable[] a, int low, int mid, int high) {
  39. //定义三个指针
  40. int i = low;
  41. int p1 = low;
  42. int p2 = mid + 1;
  43. //遍历,移动p1指针和p2指针,比较对应索引处的值,找到小的那个放到辅助数组里
  44. while (p1 <= mid && p2 <= high) {
  45. //比较对应索引处的值
  46. if (less(a[p1],a[p2])) {
  47. assist[i++] = a[p1++];
  48. } else {
  49. assist[i++] = a[p2++];
  50. }
  51. //如果p1的指针没有走完,那么顺序移动p1指针,把对应的元素放到辅助数组中
  52. while (p1 <= mid) {
  53. assist[i++] = a[p1++];
  54. }
  55. //如果p2的指针没有走完,那么顺序移动p2指针,把对应的元素放到辅助数组中
  56. while (p2 <= high) {
  57. assist[i++] = a[p2++];
  58. }
  59. //把辅助数组的元素拷贝到原数组中
  60. for (int index = low; index <= high; index++) {
  61. a[index] = assist[index];
  62. }
  63. }
  64. }
  65. }

快速排序

排序原理

  1. 首先设定一个分界值,通过该分界值将数组分成左右两部分
  2. 将大于或者等于分界值的数据放到数组右边,小于分界值的数据放到数组的左边。
  3. 左边和右边的数据可以独立排序。对于左侧的数据,又可以取一个分界值,将该数据分为左右两部分,左边放较小值,右边放较大值。右侧数据同理。
  4. 重复上述过程。可以看出这是一个递归,通过递归分别将左、右部分进行排序。

image.png