排序算法原理及实现

ゞ 浴缸里的玫瑰 2022-11-16 08:21 279阅读 0赞

排序算法原理及实现

  • 插入排序
    • 原理:
    • 实现:
  • 希尔排序
    • 原理:
    • 实现:
  • 选择排序
    • 原理:
    • 实现:
  • 冒泡排序
    • 原理:
    • 实现:
  • 堆排序
    • 原理:
    • 实现:
  • 快速排序
  • 归并排序
  • 排序算法的性能分析

排序,使一串记录,基于比较,按照递增或者递减的排列起来。
通常意义上的排序,都是原地排序(in place sort)

插入排序

原理:

我们将整个区间看做无序区间和有序区间,每次选择无序区间的第一个元素,然后在有序区间的合适位置插入。
在这里插入图片描述

实现:

  1. public static void insertSort(long[] array) {
  2. for (int i = 1; i < array.length; i++) {
  3. //[0,i)有序
  4. //[i,array.length)无序
  5. long t = array[i];
  6. int j;
  7. for (j = i - 1; j >= 0 && array[j] > t; j--) {
  8. array[j + 1] = array[j];
  9. }
  10. array[j + 1] = t;
  11. }
  12. }

ps:因为左边是有序区间,每次插入需要找到其位置,我们可以使用折半查找的方式找到其所需要插入的位置。

  1. public static void insertSort2(long[] array) {
  2. for (int i = 1; i < array.length; i++) {
  3. long t = array[i];
  4. int left = 0;
  5. int right = i;
  6. //[left,right)
  7. while (left < right) {
  8. int mid = (left + right) / 2;
  9. if (t >= array[mid]) {
  10. left = mid + 1;
  11. } else {
  12. right = mid;
  13. }
  14. }
  15. for (int j = i; j > left; j--) {
  16. array[j] = array[j - 1];
  17. }
  18. array[left] = t;
  19. }
  20. }

希尔排序

原理:

希尔排序的原理可以简单来说,将一组待排的数据,按次序依次分为若干组,然后在每一组中进行插入排序,分组每次减少,当分组为1的时候,再进行一次插入排序。
如图:相同颜色分为一组,进行插排,然后在分组,继续插排…
在这里插入图片描述

实现:

  1. public class ShellSort {
  2. public static void shellSort(long[] array) {
  3. int gap = array.length;
  4. while (gap > 1) {
  5. insertSortGap(array, gap);
  6. gap = gap / 2;
  7. }
  8. insertSortGap(array, 1);
  9. }
  10. private static void insertSortGap(long[] array, int gap) {
  11. for (int i = 1; i < array.length; i++) {
  12. long t = array[i];
  13. int j = i - gap;
  14. for (; j >= 0 && array[j] > t; j -= gap) {
  15. array[j + gap] = array[j];
  16. }
  17. array[j + gap] = t;
  18. }
  19. }
  20. }

选择排序

原理:

每一次从无序区间中选择出最大(最小)的一个元素,放入有序区间的最后面(最前面),直到全部排完。

实现:

  1. public static void selectSort(long[] array) {
  2. for (int i = 0; i < array.length - 1; i++) {
  3. int max = 0;
  4. for (int j = 1; j < array.length - i; j++) {
  5. if (array[j] > array[max]) {
  6. max = j;
  7. }
  8. }
  9. Swap.swap(array, max, array.length - i - 1);
  10. }
  11. }

冒泡排序

原理:

每走一趟,将最大(最小)的元素放在最后面,走(n-1)趟就能有序。

实现:

  1. public static void bubbleSort(long[] array) {
  2. for (int i = 0; i < array.length - 1; i++) {
  3. boolean flg = true;
  4. for (int j = 0; j < array.length - i - 1; j++) {
  5. if (array[j] > array[j + 1]) {
  6. Swap.swap(array, j, j + 1);
  7. flg = false;
  8. }
  9. }
  10. if (flg){
  11. break;
  12. }
  13. }
  14. }

堆排序

原理:

基本原理和选择排序相同,但是区别就是不通过遍历寻找最大(最小)的元素,而是通过建堆,然后将无序区间最大(最小)的元素找出来。
(建堆——将头尾交换——向下调整)
排升序要建大堆,排降序要建小堆

实现:

  1. public class HeapSort {
  2. public static void heapSort(long[] array) {
  3. creatHeap(array);
  4. for (int i = 0; i < array.length - 1; i++) {
  5. Swap.swap(array, 0, array.length - i - 1);
  6. shiftDown(array, array.length - i - 1, 0);
  7. }
  8. }
  9. //建堆
  10. private static void creatHeap(long[] array) {
  11. for (int i = (array.length - 2) / 2; i >= 0; i--) {
  12. shiftDown(array, array.length, i);
  13. }
  14. }
  15. //向下调整
  16. private static void shiftDown(long[] array, int size, int index) {
  17. //建小堆
  18. while (true) {
  19. int leftIndex = 2 * index + 1;
  20. if (leftIndex >= size) {
  21. return;
  22. }
  23. int maxIndex = leftIndex;
  24. int rightIndex = leftIndex + 1;
  25. if (rightIndex < size && array[rightIndex] > array[leftIndex]) {
  26. maxIndex = rightIndex;
  27. }
  28. if (array[maxIndex] < array[index]) {
  29. return;
  30. }
  31. long t = array[index];
  32. array[index] = array[maxIndex];
  33. array[maxIndex] = t;
  34. index = maxIndex;
  35. }
  36. }
  37. }

快速排序

关于快速排序相对较复杂,请点击传送门:

链接:快速排序

归并排序

关于归并排序详情,请点击传送门:

链接:归并排序

排序算法的性能分析

关于各个算法,时间复杂度、空间复杂度总结分析:

链接:性能分析

发表评论

表情:
评论列表 (有 0 条评论,279人围观)

还没有评论,来说两句吧...

相关阅读

    相关 排序算法】堆排序原理Java实现

    1、基本思想 堆是一种特殊的树形数据结构,其每个节点都有一个值,通常提到的堆都是指一颗完全二叉树,根结点的值小于(或大于)两个子节点的值,同时,根节点的两个子树也分别是一

    相关 排序原理算法实现

    堆排序 堆排序是利用堆的性质进行的一种选择排序。下面先讨论一下堆。 1.堆 堆实际上是一棵完全二叉树,其任何一非叶节点满足性质: Key\[i\]<=key\[2i+