常用的排序算法包括:

冒泡排序:

每次在无序队列里将相邻两个数依次进行比较,将小数调换到前面, 逐次比较,直至将最大的数移到最后。最将剩下的N-1个数继续比较,将次大数移至倒数第二。依此规律,直至比较结束。时间复杂度:O(n^2)

选择排序:

每次在无序队列中“选择”出最大值,放到有序队列的最后,并从无序队列中去除该值(具体实现略有区别)。时间复杂度:O(n^2)

直接插入排序:

始终定义第一个元素为有序的,将元素逐个插入到有序排列之中,其特点是要不断的 移动数据,空出一个适当的位置,把待插入的元素放到里面去。时间复杂度:O(n^2)

希尔排序:

希尔排序是对直接插入排序的改进,希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

快速排序:

递归地将数组一分为2,左边是所有比第一个数小的,右边是所有比第一个数大的。这其中涉及到如何移动交换的技巧问题。本题为挖坑填坑模式。时间复杂度:O(nlogn)

堆排序:

对需要排序的数组首先建立堆,然后(如果最终是由小到大排序)依次交换根位置与最后一个节点位置的数值,之后调整堆,循环往复。时间复杂度:O(nlogn)。关于堆这一数据结构以及堆排序可以参考百度百科:堆排序

归并排序:给定两个已经排好序(由小到大)的数组,归并排序的意思是,选取数组A中的第一个值,与另一个数组B中的第一个值比较,每找到一个较小的值就写入新的数组C,直到所有的值都大于此值时,将此值写入C,选取数组A的一个值作为对照值,重复上面的操作。时间复杂度:O(nlogn)

关于各种排序算法的稳定性:

1) 稳定的:如果存在多个具有相同排序码的记录,经过排序后,这些记录的相对次序仍然保持不变,则这种排序算法称为稳定的。

插入排序、冒泡排序、归并排序、分配排序(桶式、基数)都是稳定的排序算法。

2) 不稳定的:否则称为不稳定的。

直接选择排序、堆排序、shell排序、快速排序都是不稳定的排序算法。

关于不同引用场景下使用不同的算法:

(1) 若n较小(如n≤50),可采用直接插入或直接选择排序。

当记录规模较小时,直接插入排序较好;否则因为直接选择移动的记录数少于直接插人,应选直接选择排序为宜。

(2) 若文件初始状态基本有序(指正序),则应选用直接插人、冒泡或随机的快速排序为宜;

(3) 若n较大,则应采用时间复杂度为O(nlgn)的排序方法:快速排序、堆排序或归并排序。

快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;

堆排序所需的辅助空间少于快速排序,并且不会出现快速排序可能出现的最坏情况。这两种排序都是不稳定的。

若要求排序稳定,则可选用归并排序。但本章介绍的从单个记录起进行两两归并的  排序算法并不值得提倡,通常可以将它和直接插入排序结合在一起使用。先利用直接插入排序求得较长的有序子文件,然后再两两归并之。因为直接插入排序是稳定 的,所以改进后的归并排序仍是稳定的。

代码1:冒泡排序,选择排序,直接插入排序,希尔排序,快速排序代码。

java 排序算法时间复杂度测试 java排序的时间复杂度_Java堆排序的时间复杂度

java 排序算法时间复杂度测试 java排序的时间复杂度_Java堆排序的时间复杂度_02

1 /**

2 * 冒泡排序: 每次在无序队列里将相邻两个数依次进行比较,将小数调换到前面, 逐次比较,直至将最大的数移到最后。3 * 最将剩下的N-1个数继续比较,将次大数移至倒数第二位。 依此规律,直至比较结束。4 */

5 public static void bubbleSort(int[] a) {6 int n =a.length;7 for (int i = 0; i < n - 1; i++) {8 for (int j = 0; j < n - i - 1; j++) {9 if (a[j] > a[j + 1]) {10 int temp = a[j + 1];11 a[j + 1] =a[j];12 a[j] =temp;13 }14 }15 }16 }17

18 /**

19 * 选择排序:每次在无序队列中“选择”出最大值,放到有序队列的最后,并从无序队列 中去除该值(具体实现略有区别)。20 */

21 public static void selectSort(int[] a) {22 int n =a.length;23 int max_index = 0;24 for (int i = n - 1; i >= 0; i--) {25 max_index =i;26 for (int j = 0; j <= i; j++) {27 if (a[j] >a[max_index])28 max_index =j;29 }30 if (max_index !=i) {31 int temp =a[i];32 a[i] =a[max_index];33 a[max_index] =temp;34 }35 }36 }37

38 /**

39 * 插入排序:始终定义第一个元素为有序的,将元素逐个插入到有序排列之中,其特点是要不断的 移动数据,空出一个适当的位置,把待插入的元素放到里面去。40 */

41 public static void insertSort(int[] a) {42 int n =a.length;43 int j = 0;44 for (int i = 1; i < n; i++) {45 j = i - 1;46 int temp =a[i];47 while (j >= 0 && a[j] >temp) {48 a[j + 1] =a[j];49 j--;50 }51 a[j + 1] =temp;52 for (intm : a) {53 System.out.print(m + ",");54 }55 System.out.println();56 //for (int j = i; j > 0; j--) {57 //if (a[j] < a[j - 1]) {58 //int temp = a[j];59 //a[j] = a[j - 1];60 //a[j - 1] = temp;61 //}62 //}

63 }64 }65

66 /**

67 * 快速排序:递归地将数组一分为2,左边是所有比第一个数小的,右边是所有比第一个数大的68 */

69 public static void quickSort(int[] a) {70 quickSort(a, 0, a.length - 1);71 }72

73 private static void quickSort(int[] a, int l, intr) {74 if (l

76 int mid =a[l];77 int i = l, j =r;78 while (i mid)80 j--;81 if (i

94 /**

95 * 希尔排序是对直接插入排序的改进,希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,96 * 当增量减至1时,整个文件恰被分成一组,算法便终止。97 *98 *@parama99 */

100 public static void shellSort(int[] a) {101 int d =a.length;102 while (true) {103 d = d / 2;104 for (int x = 0; x < d; x++) {//分组105 //对每组进行直接插入排序

106 for (int i = x + d; i < a.length; i = i +d) {107 int temp = a[i];//记录要插入的值

108 intj;109 //将要插入的值插入到正确位置,这一过程中不断检测前面的数,如果相比较大,则同时移动一次

110 for (j = i - d; j >= 0 && a[j] > temp; j = j -d) {111 a[j + d] =a[j];112 }113 a[j + d] =temp;114 }115 }116 if (d == 1) {117 break;118 }119 }120 }

View Code

代码2:推排序(由于java版比较长,所以另写一个)

java 排序算法时间复杂度测试 java排序的时间复杂度_Java堆排序的时间复杂度

java 排序算法时间复杂度测试 java排序的时间复杂度_Java堆排序的时间复杂度_02

1

public classHeapSort {2 private static int[] sort = new int[] { 1, 0, 10, 20, 3, 5, 6, 4, 9, 8, 12, 17, 34, 11};3
4 public static voidmain(String[] args) {5 System.out.println(sort.length);6 buildMaxHeapify(sort);7 heapSort(sort);8 print(sort);9 }10
11 private static void buildMaxHeapify(int[] data) {12 //没有子节点的才需要创建最大堆,从最后一个的父节点开始
13 int startIndex = getParentIndex(data.length - 1);14 //从尾端开始创建最大堆,每次都是正确的堆
15 for (int i = startIndex; i >= 0; i--) {16 maxHeapify(data, data.length, i);17 }18 }19
20 /**
21 * 创建最大堆22 *23 * @paramdata24 * @paramheapSize需要创建最大堆的大小,一般在sort的时候用到,因为最多值放在末尾,末尾就不再归入最大堆了25 * @paramindex当前需要创建最大堆的位置26 */
27 private static void maxHeapify(int[] data, int heapSize, intindex) {28 //当前点与左右子节点比较
29 int left =getChildLeftIndex(index);30 int right =getChildRightIndex(index);31
32 int largest =index;33 if (left < heapSize && data[index] 
40 if (largest !=index) {41 int temp =data[index];42 data[index] =data[largest];43 data[largest] =temp;44 maxHeapify(data, heapSize, largest);45 }46 }47
48 /**
49 * 排序,最大值放在末尾,data虽然是最大堆,在排序后就成了递增的50 *51 * @paramdata52 */
53 private static void heapSort(int[] data) {54 //末尾与头交换,交换后调整最大堆
55 for (int i = data.length - 1; i > 0; i--) {56 int temp = data[0];57 data[0] =data[i];58 data[i] =temp;59 maxHeapify(data, i, 0);60 }61 }62
63 /**
64 * 父节点位置65 *66 * @paramcurrent67 *@return
68 */
69 private static int getParentIndex(intcurrent) {70 return (current - 1) >> 1;71 }72
73 /**
74 * 左子节点position注意括号,加法优先级更高75 *76 * @paramcurrent77 *@return
78 */
79 private static int getChildLeftIndex(intcurrent) {80 return (current << 1) + 1;81 }82
83 /**
84 * 右子节点position85 *86 * @paramcurrent87 *@return
88 */
89 private static int getChildRightIndex(intcurrent) {90 return (current << 1) + 2;91 }92
93 private static void print(int[] data) {94 int pre = -2;95 for (int i = 0; i < data.length; i++) {96 if (pre < (int) getLog(i + 1)) {97 pre = (int) getLog(i + 1);98 System.out.println();99 }100 System.out.print(data[i] + "|");101 }102 }103
104 /**
105 * 以2为底的对数106 *107 * @paramparam108 *@return
109 */
110 private static double getLog(doubleparam) {111 return Math.log(param) / Math.log(2);112 }113 }
View Code

代码3:top-K问题

java 排序算法时间复杂度测试 java排序的时间复杂度_Java堆排序的时间复杂度

1 /**
2 * 使用最大堆进行top K的选取3 */
4 public static int[] topK(int[] a, intk) {5 int[] res = new int[k];6 if (k >a.length) {7 System.err.println("k larger than length of array");8 returnres;9 }10 for (int i = 0; i < a.length; i++) {11 if (a[i] > res[0]) {12 res[0] =a[i];13 for (int j = 0; j < k && 2 * j + 1 res[2 * j + 2]) {16 if (res[j] > res[2 * j + 2]) {17 int temp = res[2 * j + 2];18 res[2 * j + 2] =res[j];19 res[j] =temp;20 j = 2 * j + 2;21 tag1 = 1;22 }23 } else{24 if (res[j] > res[2 * j + 1]) {25 int temp = res[2 * j + 1];26 res[2 * j + 1] =res[j];27 res[j] =temp;28 j = 2 * j + 1;29 tag2 = 1;30 }31 }32 if (tag1 == 0 && tag2 == 0)33 break;34 }35 }36 }37 returnres;38 }
View Code