排序算法可以分为:

  • 内部排序:数据记录在内存中进行排序。
  • 外部排序:因排序的数据很大,内存不能容纳全部的排序记录,在排序过程中需要访问外存。

常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序、计数排序、桶排序。

其中比较类排序有:冒泡排序、快速排序、插入排序、希尔排序、选择排序、堆排序、归并排序

非比较类排序:计数排序、基数排序、桶排序

 1、冒泡排序

算法步骤:从头或尾开始比较相邻的元素,如果逆序则交换,这样每遍历一次就会确定一个数的位置,重复以上步骤知道排序完成

 1 public int[] bubbleSort(int[] arr){
 2     for(int i=1;i<arr.length;i++){
 3         boolean flag=true;
 4         for(int j=0;j<arr.length-i;j++){
 5             if(arr[j]>arr[j+1]){
 6                 int temp=arr[j];
 7                 arr[j]=arr[j+1];
 8                 arr[j+1]=temp;
 9                 flag=false;
10             }
11         }
12         if(flag)break;
13     }
14     return arr;
15 }
bubbleSort

此处对代码做了一个小优化,加入了 is_sorted Flag,目的是将算法的最佳时间复杂度优化为 O(n),即当原输入序列就是排序好的情况下,该算法的时间复杂度就是 O(n)。

算法分析:

  • 稳定性:稳定
  • 时间复杂度:最佳:O(n) ,最差:O(n2), 平均:O(n2)
  • 空间复杂度:O(1)
  • 排序方式:交换排序

2、选择排序

算法步骤:从未排序的序列找到最小或者最大的放在指定位置,直到所有元素均有序

 1 public static int[] selectionSort(int[] arr) {
 2     for (int i = 0; i < arr.length - 1; i++) {
 3         int minIndex = i;
 4         for (int j = i + 1; j < arr.length; j++) {
 5             if (arr[j] < arr[minIndex]) {
 6                 minIndex = j;
 7             }
 8         }
 9         if (minIndex != i) {
10             int tmp = arr[i];
11             arr[i] = arr[minIndex];
12             arr[minIndex] = tmp;
13         }
14     }
15     return arr;
16 }
selectionSort

算法分析:

  • 稳定性:不稳定
  • 时间复杂度:最佳:O(n2) ,最差:O(n2), 平均:O(n2)
  • 空间复杂度:O(1)
  • 排序方式:选择排序

3、插入排序

步骤:对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

public static int[] insertionSort(int[] arr) {
    for (int i = 1; i < arr.length; i++) {
        int preIndex = i - 1;
        int current = arr[i];
        while (preIndex >= 0 && current < arr[preIndex]) {
            arr[preIndex + 1] = arr[preIndex];
            preIndex -= 1;
        }
        arr[preIndex + 1] = current;
    }
    return arr;
}

  

  • 稳定性:稳定
  • 时间复杂度:最佳:O(n) ,最差:O(n2), 平均:O(n2)
  • 空间复杂度:O(1)
  • 排序方式:插入排序

4、希尔排序

算法步骤:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录 “基本有序” 时,再对全体记录进行依次直接插入排序。

先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,具体算法描述:

  • 选择一个增量序列 {t1, t2, …, tk},其中 (ti>tj, i<j, tk=1)
  • 按增量序列个数 k,对序列进行 k 趟排序;
  • 每趟排序,根据对应的增量 t,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。