排序算法(一)

168 阅读4分钟

冒泡排序

初始 相邻两元素若左大右小,则交换,每一次都将最大的元素交换至末尾。

void BubbleSort_bas(int arr[], int len){
    for(int i = 0; i < len; i++){
        for(int j = 0; j < len - i - 1; j++){
            if(arr[j] > arr[j+1]){
                int temp = arr[j+1];
                arr[j+1] = arr[j];
                arr[j] = temp;
            }
        }
    }
}

优化 记录每次交换的最终位置(即后面元素已有序)作为下一次内层扫描的终点,若某次外层扫描发现内层扫描完后并未发生元素交换(即有序)则直接退出。

void BubbleSort_pre(int arr[], int len){
    for(int i = 0; i < len; i++){
        int last = len - 1;
        for(int j = 0; j < len - i - 1; j++){
            if(arr[j] > arr[j+1]){
                int temp = arr[j+1];
                arr[j+1] = arr[j];
                arr[j] = temp;
                last = j;
            }
        }
        i = len - last - 1;
    }

时间复杂度:O(n^2) 空间复杂度:O(1) 稳定性:稳定

选择排序

扫描n次,每次将最大的元素放在最后一个位置,然后对前n-1个元素再进行上述操作,直到有序。

void SelectSort(int arr[], int len){
  for(int i = 0; i < len; i++){
      int max = 0;
      for(int j = 0; j < len - i; j++){
          if(arr[max] <= arr[j])
              max = j;
      }
      int temp = arr[max];
      arr[max] = arr[len - i - 1];
      arr[len - i - 1] = temp;
  }
}

时间复杂度:O(n^2) 空间复杂度:O(1) 稳定性:稳定

插入排序

初始 对一个需要排序的元素,从后往前遍历,遇到大的则交换位置。

void InsertSort_bas(int arr[], int len){
    for(int i = 1; i < len; i++){
        for(int j = i; j > 0 && arr[j] < arr[j - 1]; j--){
            int temp = arr[j];
            arr[j] = arr[j - 1];
            arr[j - 1] = temp;
        }
    }
}

优化 对一个需要排序的元素,二分地查找比其大的最小元素位置,将其备份后,比其大的元素向后挪动一位并将其插入到空余位置。

void InsertSort_pre(int arr[], int len){
    for(int i = 1; i < len; i++){
        int temp = arr[i], L = 0, R = i - 1, mid = (L + R ) / 2;
        while(L < R){
            if(arr[mid] > temp)
                R = mid;
            else
                L = mid + 1;
        }
        for(int j = i; j > L; j--)
            arr[j] = arr[j - 1];
        arr[L] = temp;
    }
}

时间复杂度:O(n^2) 空间复杂度:O(1) 稳定性:原始不稳定可优化为稳定