1. 程式人生 > 其它 >六大排序演算法:插入排序、希爾排序、選擇排序、氣泡排序、堆排序、快速排序

六大排序演算法:插入排序、希爾排序、選擇排序、氣泡排序、堆排序、快速排序

1.插入排序

1.從第一個元素開始,該元素可以認為已經被排序
2.取下一個元素tem,從已排序的元素序列從後往前掃描
3.如果該元素大於tem,則將該元素移到下一位
4.重複步驟3,直到找到已排序元素中小於等於tem的元素
5.tem插入到該元素的後面,如果已排序所有元素都大於tem,則將tem插入到下標為0的位置
6.重複步驟2~5

#include <bits/stdc++.h>
using namespace std;

int main(){
  int n, tem = 0;
  cin >> n;
  int a[n];
  for(int i = 0; i < n; i ++){


    cin >> a[i];
}

  for(int i = 1; i < n; i ++){
    for(int j = i; j >= 1; j --)
    if(a[j] < a[j - 1]){
      tem = a[j];
      a[j] = a[j - 1];
      a[j - 1] = tem;
    }
  }

for(int i = 0; i < n; i ++)

cout << a[i] << " " ; //偷個懶
}

時間複雜度:最壞情況下為O(N*N),此時待排序列為逆序,或者說接近逆序
      最好情況下為O(N),此時待排序列為升序,或者說接近升序。
空間複雜度:O(1)

2.希爾排序

1.先選定一個小於N的整數gap作為第一增量,然後將所有距離為gap的元素分在同一組,並對每一組的元素進行直接插入排序。然後再取一個比第一增量小的整數作為第二增量,重複上述操作…
2.當增量的大小減到1時,就相當於整個序列被分到一組,進行一次直接插入排序,排序完成。

核心:插入排序 + 分組

#include <bits/stdc++.h>


using namespace std;

int main(){
  int n, j;
  cin >> n;
  int a[n];
  for(int i = 0; i < n; i ++)
    cin >> a[i];

  int d, temp;
  for(d = n / 2; d >= 1;d = d / 2){
    for(int i = d; i < n; i ++){
      temp = a[i];
      for(j = i - d; j >= 0 && temp < a[j]; j = j - d){
        a[j + d] = a[j];
      }
      a[j + d] = temp;
    }
  }
  for(int i = 0; i < n; i ++)
    cout << a[i] << " ";

  return 0;
}

時間複雜度平均:O(N^1.3)
空間複雜度:O(1)

3.選擇排序

每次從待排序列中選出一個最小值,然後放在序列的起始位置,直到全部待排資料排完即可。
實際上,我們可以一趟選出兩個值,一個最大值一個最小值,然後將其放在序列開頭和末尾,這樣可以使選擇排序的效率快一倍。

#include <bits/stdc++.h>
using namespace std;

void swap(int &a, int &b)
{
  int temp = a;
  a = b;
  b = temp;
}

int main(){
  int n, temp;
  cin >> n;
  int a[n];
  for(int i = 0; i < n; i ++)
    cin >> a[i];

  for(int i = 0; i < n; i ++){
    int min = i;
    for(int j = i + 1; j < n; j ++){
      if(a[j] < a[min]){
        min = j;
      }
    }
  swap(a[i], a[min]);
  }

for(int i = 0; i < n; i ++)
cout << a[i] << " ";
}

4.氣泡排序

左邊大於右邊交換一趟排下來最大的在右邊

#include <bits/stdc++.h>
using namespace std;

void swap(int &a, int &b)
{
  int temp = a;
  a = b;
  b = temp;
}

int main(){
  int n;
  cin >> n;
  int a[n];
  for(int i = 0; i < n; i ++){
  cin >> a[i];
}

  for(int i = 1; i < n; i ++){
    for(int j = 0; j < n - 1; j ++){
      if(a[j] > a[j + 1])
      swap(a[j], a[j + 1]);
    }
  }

  for(int i = 0; i < n; i ++){
    cout << a[i] <<" ";
  }
}

時間複雜度:最壞情況:O(N^2)
      最好情況:O(N)
空間複雜度:O(1)

5.堆排序(先留個坑吧)堆,向下調整演算法,向上調整演算法,陣列建堆演算法,堆排序,建堆時間複雜度的推理_HanMeng的部落格-CSDN部落格

補一個桶排序

當存在“一個桶中有多個元素”的情況時,要先使用合適的排序演算法對各個痛內的元素進行排序,然後再根據桶的次序逐一取出所有元素,最終得到的才是一個有序序列。

6.最後是快速排序

我用的模板是Y總的

#include <iostream>

using namespace std;

const int N = 100010;

int q[N];

void quick_sort(int q[], int l, int r)
{
  if (l >= r) return;

  int i = l - 1, j = r + 1, x = q[l + r >> 1];
  while (i < j)
  {
    do i ++ ; while (q[i] < x);
    do j -- ; while (q[j] > x);
    if (i < j) swap(q[i], q[j]);
  }

  quick_sort(q, l, j);
  quick_sort(q, j + 1, r);
}

int main()
{
  int n;
  scanf("%d", &n);

  for (int i = 0; i < n; i ++ ) scanf("%d", &q[i]);

  quick_sort(q, 0, n - 1);

  for (int i = 0; i < n; i ++ ) printf("%d ", q[i]);

  return 0;
}

這就是六大排序的主要內容了

先寫到這裡

快速排序還會寫