六大排序算法:插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序

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;
}

这就是六大排序的主要内容了

先写到这里

快速排序还会写

 

上一篇:vmware虚拟机安装deepin20全过程


下一篇:[LeetCode刷题] 476. 数字的补数--Java实现