基础排序算法

189 阅读3分钟

基础排序算法

1、冒泡排序

冒泡排序,顾名思义,按泡泡一样上浮起来。每一次比较2个相邻的数字,进行交换,交换到最后,便完全了一个数字的排序。进行N次比较,就完成了N个数字的排序。
例如:
2 4 8 3 9 1 按从小到大排序

在每一次的冒泡中,把相邻的数据按照大小交换。 java实现如下

for (int i = 0; i < n; ++i) {
    // 提前退出冒泡循环,当在一次冒泡过程中,都没有一个数据发送交互,则可以提前退出循环,因为数据已经排好序了,节省了多余的循环
    boolean flag = false;
    for (int j = 0; j < n - i - 1; ++j) {
      if (a[j] > a[j+1]) { 
        // 按顺序进行交换
        int tmp = a[j];
        a[j] = a[j+1];
        a[j+1] = tmp;
        // 表示有数据交换 
        flag = true;       
      }
    }
    if (!flag) break;  // 没有数据交换,提前退出
  }

从代码中可以看出,冒泡排序是一种稳定的排序算法。稳定的判断在于,当2数相同时,排序前后,2数的顺序是否会发生变化

2、选择排序

选择排序:在每一次排序中,查到最小(大)元素,按序排列。最后排列出来的就是排序的结果。
git图如下,转自其他网站

java代码如下

    // 总共要经过 N-1 轮比较
    for (int i = 0; i < arr.length - 1; i++) {
        int min = i;

        // 每轮需要比较的次数 N-i
        for (int j = i + 1; j < arr.length; j++) {
            if (arr[j] < arr[min]) {
                // 记录目前能找到的最小值元素的下标
                min = j;
            }
        }
        // 将找到的最小值和i位置所在的值进行交换
        if (i != min) {
            int tmp = arr[i];
            arr[i] = arr[min];
            arr[min] = tmp;
        }

    }

当存在2个相同的数时,2个数的顺序在排序中就无法保持原样,故不稳定

3、插入排序

把数列分为2个区域,一个是已排序区域,一个是未排序区域。每次从未排序的区域里面找一个元素,插入已排序区中 如下图

java代码如下

for (int i = 1; i < n; ++i) {
    int value = a[i];
    int j = i - 1;
    // 查找插入的位置
    for (; j >= 0; --j) {
      if (a[j] > value) {
       // 数据整体向后移动
        a[j+1] = a[j]; 
      } else {
        break;
      }
    }
    // 插入数据
    a[j+1] = value; 
  }

当相同的元素出现时,保持原来的顺序不变,插入排序是稳定的排序算法

4、快速排序

单纯从时间复杂度来讲,快速排序最好。 选择一个基准数,把数字按这个基准数分为2部分,一部分大于基准数,一部分都小于基准数。再从2部分中,分布选择一个基准数,各自进行上诉操作。以此类推,直到不能再分。
例如:
4 2 8 3 9 1 按从小到大排序

第一次的基准数设置为 4
{ 3 2 1 } 4 { 9 8 }
第二次分别对 {321} 和{98} 进行排序
321 选择 3 {1 2} 3
98 选择 8 {8,9} 结束,因为无法再分
第三次 对{1 2} 排序
...
最后得到
123489 序列

java代码如下

private static void quickSort(int[] arr, int low, int high) {
        if(low > high){
            return;
        }
        int temp = arr[low];
        int i = low;
        int j = high;
        while (i < j){

            while(temp <= arr[j] && i<j){
                j--;
            }

            while(temp >= arr[i] && i<j){
                i++;
            }

            if(i <j){
                int t = arr[j];
                arr[j] = arr[i];
                arr[i] =t;
            }
        }
        arr[low] =arr[i];
        arr[i] = temp;
        quickSort(arr,low,j-1);
        quickSort(arr,j+1,high);

    }

在相同元素的情况下,此时也无法保证稳定性。选择基准数的不同,不一定还能保持原有的顺序。