七大经典排序算法,了解一下?

Posted 欢迎关注我的公众号:java技术学习之道,长期分享各种技术文

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了七大经典排序算法,了解一下?相关的知识,希望对你有一定的参考价值。

---恢复内容开始---

作者 : liuyang0
来源 : 博客园

常见排序算法总结与实现

本文使用Java实现这几种排序。
以下是对排序算法总体的介绍。

冒泡排序

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

时间复杂度:O(n^2),最优时间复杂度:O(n),平均时间复杂度:O(n^2)

 1public static void bubbleSort(Comparable[] a) {
2 int j, flag;
3 Comparable temp;
4 for (int i = 0; i < a.length; i++) {
5 flag = 0;
6 for (j = 1; j < a.length - i; j++) {
7 if (a[j].compareTo(a[j - 1]) < 0) {
8 temp = a[j];
9 a[j] = a[j - 1];
10 a[j - 1] = temp;
11 flag = 1;
12 }
13 }
14 // 如果没有交换,代表已经排序完毕,直接返回
15 if (flag == 0) {
16 return;
17 }
18 }
19}

插入排序

  1. 从第一个元素开始,该元素可以认为已经被排序
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置
  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
  5. 将新元素插入到该位置后
  6. 重复步骤2~5

时间复杂度:O(n^2),最优时间复杂度:O(n),平均时间复杂度:O(n^2)

下面展示了三种插入排序的实现,第二种方法减少了交换次数,第三种采用二分查找法查到插入点。

 1public static void insertionSort(Comparable[] a) {
2 int length = a.length;
3 Comparable temp;
4 for (int i = 1; i < length; i++) {
5 for (int j = i; j > 0 && a[j].compareTo(a[j - 1]) < 0; j--) {
6 temp = a[j];
7 a[j] = a[j - 1];
8 a[j - 1] = temp;
9 }
10 }
11}
12
13// 对实现Comparable的类型进行排序,先将大的元素都向右移动,减少一半交换次数
14public static void insertionSort(Comparable[] a) {
15 int length = a.length;
16 Comparable temp;
17 int j;
18 for (int i = 1; i < length; i++) {
19 temp = a[i];
20 for (j = i; j > 0 && temp.compareTo(a[j - 1]) < 0; j--) {
21 a[j] = a[j - 1];
22 }
23 a[j] = temp;
24 }
25}
26
27// 二分插入排序,使用二分查找找到插入点,然后进行移位
28public static void insertionSort(Comparable[] a) {
29 int length = a.length;
30 Comparable temp;
31 int j;
32 for (int i = 1; i < length; i++) {
33 if (a[i].compareTo(a[i - 1]) < 0) {
34 temp = a[i];
35 int index = binarySearch(a, a[i], 0, i - 1);
36 for (j = i - 1; j >= index; j--) {
37 a[j + 1] = a[j];
38 }
39 a[index] = temp;
40 }
41 }
42}
43
44private static int binarySearch(Comparable[] a, Comparable target, int start, int end) {
45 int mid;
46 while (start <= end) {
47 mid = (start + end) >> 1;
48 if (target.compareTo(a[mid]) < 0) {
49 end = mid - 1;
50 } else {
51 start = mid + 1;
52 }
53 }
54 return start;
55}

选择排序

首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到已排序序列的末尾。

时间复杂度:O(n^2),最优时间复杂度:O(n^2),平均时间复杂度:O(n^2)

 1public static void selectionSort1(Comparable[] a) {
2 int length = a.length;
3 int min;
4 Comparable temp;
5 for (int i = 0; i < length; i++) {
6 min = i;
7 for (int j = i + 1; j < length; j++) {
8 if (a[j].compareTo(a[min]) < 0) {
9 min = j;
10 }
11 }
12 temp = a[min];
13 a[min] = a[i];
14 a[i] = temp;
15 }
16}

希尔排序

希尔排序通过将比较的全部元素分为几个区域来提升插入排序的性能。这样可以让一个元素可以一次性地朝最终位置前进一大步。然后算法再取越来越小的步长进行排序,算法的最后一步就是普通的插入排序,但是到了这步,需排序的数据几乎是已排好的了(此时插入排序较快)。

时间复杂度:根据步长而不同,最优时间复杂度:O(n),平均时间复杂度:根据步长而不同

 1public static void shellSort(Comparable[] a) {
2 int length = a.length;
3 int h = 1;
4 Comparable temp;
5 while (h < length / 3) {
6 h = 3 * h + 1;
7 }
8 while (h >= 1) {
9 for (int i = h; i < length; i++) {
10 for (int j = i; j >= h && a[j].compareTo(a[j - h]) < 0; j -= h) {
11 temp = a[j];
12 a[j] = a[j - h];
13 a[j - h] = temp;
14 }
15 }
16 h /= 3;
17 }
18}

堆排序

  1. 创建最大堆(Build_Max_Heap):将堆所有数据重新排序
  2. 堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算

时间复杂度:O(nlogn),最优时间复杂度:O(nlogn),平均时间复杂度:O(nlogn)

 1public static void heapSort(Comparable[] a) {
2 int length = a.length;
3 Comparable temp;
超详细总结基于比较的七大经典 排序 -- 不会的童鞋快进来补习

数据结构之七大排序算法

✨✨[数据结构]——最经典的七大排序(超详细近两万字教程,你值得拥有)✨✨

七大排序算法之冒泡排序

面试必备排序算法 --快速排序

面试相关-七大排序算法:图解+动图+最直观的代码分析_性能比较