常见的排序算法
算法分类
1、排序
- 比较类排序
2、复杂度
相关概念
- 稳定:如果 a 本来在 b 前面,而a = b ,排序之后 a 仍然在 b 的前面
- 不稳定:如果 a 本来 在b的前面,而 a = b ,排序之后 a 可能在 b 的后面
- 时间复杂度:对排序数据的总的操作数,反映当 n 变化时,操作次数呈什么变化
- 空间复杂度: 指算法计算机内执行时所需存空间的度量,也是数据规模 n 的函数
几种常见排序(已学)
1、冒泡排序(Bubble Sort)
~~注:重复地走访序列,一次比较两个元素,如果顺序错误就交换过来,重复地进行直到没有再需要交换,也就说该数列排序完成------->这个算法的名字是因为越小的元素会经由交换慢慢“浮”到顶端
动图展示

代码实现
function bubbleSort(arr) { var len = arr.length; for (var i = 0; i < len - 1; i++) { for (var j = 0; j < len - 1 - i; j++) { //每次循环最大的元素都被放到最后,就不用管了 if (arr[j] > arr[j+1]) { // 相邻元素两两对比 var temp = arr[j+1]; // 元素交换 arr[j+1] = arr[j]; arr[j] = temp; } } } return arr; }
课上讲的模板类写法:
template<class T> void mySwap(T &x,T &y) { T temp = x; x = y; y = temp; } template<class T> void bubbldeSort(T a[],int n) { int i= n-1 ; while(i>0){ int lastExchange = 0;//每次都值为 0 ,如果下面的 if语句 不成立,退出循环,说明排序完成 //(a[j]<a[j+1])都成立 for(int j=0;j<i;j++) if(a[j+1]<a[j]) { mySwap(a[j],a[j+1]); lastExchange = j; //第一次循环这个 j = n-1,a[j+1]包括后面的数就不用管了 } i = lastExchange; } }
2、选择排序(Selection Sort)
~~注:首先在未排序序列中找到最小(大)的元素,存放到排序序列的起始位置,然后再从剩余未排序序列元素中继续寻找最小元素,然后放到已排序序列的末尾。以此类推,直到排序完毕。
动图
](https://imgchr.com/i/aItpqJ)
代码实现;
function selectionSort(arr) { var len = arr.length; var minIndex, temp; for (var i = 0; i < len - 1; i++) { minIndex = i; //记录未排序的第一个数,方便后面最小的数与其交换 for (var j = i + 1; j < len; j++) { if (arr[j] < arr[minIndex]) { // 寻找最小的数 minIndex = j; // 将最小数的索引保存 } } temp = arr[i]; arr[i] = arr[minIndex]; arr[minIndex] = temp; //将 i 和最小的数交换 ,然后 i 往后移一位,前面是已经排好的序列 } return arr; }
3、插入排序
~注:描述--->
- 第一个元素已经排序
- 取出下一个元素,在已经排序的元素序列中从后往前扫描
- 如果该元素(已排序)大于新元素,将该元素移至下一个位置
- 重复3,直到找到已排序的元素小于或等于新元素的位置

代码实现:
function insertionSort(arr) { var len = arr.length; var preIndex, current; for (var i = 1; i < len; i++) { preIndex = i -1; current = arr[i]; //前面的数都是已经排好序的 while (preIndex >= 0 && arr[preIndex] > current) { //后面的数比前面的大就循环,如果小于或等于就停止循环,进行插入 arr[preIndex + 1] = arr[preIndex]; //往后挪位置 preIndex--; } arr[preIndex+1] = current; //上面arr[preIndex]往后移了,此时arr[preIndex]为无用值,又减了一,所以要加1; } return arr; } //注释1:从下标为1的元素开始遍历,记作temp-->然后从temp向前遍历将元素往后挪位,直到不满足条件插入此元素
c++模板类写法:
template<class T> void insertionSort(T a[],int n) { int i,j; T temp; for(int i=1;i<n;i++) { int j=i; T temp = a[i]; while(j>0 && temp<a[j-1]) { a[j]=a[j-1]; //这里j值并没有改变,下面减去一才是要填充的位置 j--; } a[j]=temp; //a[j-1]被移动到后面的序列去了, j-1是无用数据 } } 3 2 5 4 9 8 7 temp = 2 2 3 5 4 9 8 7 temp = 5 2 3 4 5 9 8 7 temp = 5 //注释2:从下标为1开始循环(因为要j-1不能越界),如果前面的元素比temp(循环选定元素)大,说明要后退一位,以便留一个位置给temp,就这样一直后移直到找到一个数 < temp
4、计数排序
适用于在较小范围内的数字;
- 计数排序可以不用进行比较两数大小的操作
- 另外用一个数组记录出现数字的次数,下标表示数字,数组下标对应的元素表示该数字出现的次数
#include<bits/stdc++.h> using namespace std; void countSort(vector<int>& array){ int max = array[0]; for(int i=1;i<array.size();i++){// 找出最大值 if(array[i]>max){ max = array[i]; } } vector<int> countArray(max+1); // 容量为max+1 for(int i=0;i<array.size();i++){ countArray[array[i]]++; } int index = 0;// countArray下标代表数字,对应的元素值表示 //出现的次数 ================================ for(int i=0;i<countArray.size();i++){ for(int j=0;j<countArray[i];j++){ array[index++] = i; // 直接修改原数组(参数) ================================ } } } int main(){ vector<int> a={4,4,6,5,3,2,8,1,7,5,6,0,10}; countSort(a); for(vector<int>:: iterator it = a.begin();it!=a.end();it++ ){ cout<<*it<<endl; } return 0; }
5、快速排序
- 基准元素
- 两边向中间循环查找
双边循环
#include <iostream> #include <vector> #define N 10 using namespace std; void sawp(int &a,int &b)// 交换两个数 { int temp; temp = a; a = b; b = temp; } void quickSort(int left,int right,vector<int> & a) { if(left >= right) return; int i,j,base; i = left, j =right; base = a[left];// 基准元素 while(i < j) { while(a[j]>=base && i < j) //i <j 基本条件 j--; while(a[i]<=base && i < j) i++; if(i < j) // 有可能此时i==j swap(a[i],a[j]); //交换左边和右边的值,一个大于基准值,一个小于基准值 } a[left] = a[i]; a[i] = base; quickSort(left,i-1,a);//对剩余的部分进行快速排序 quickSort(i+1,right,a);// }
y总模板
#include <iostream> using namespace std; const int N = 1000010; 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; }
单边循环>
#include <iostream> #include <vector> #define N 10 using namespace std; void sawp(int &a, int &b) { // 交换两个数 int temp; temp = a; a = b; b = temp; } void quickSort(vector<int> &a, int L, int R) { if(L>=R){ return; // 递归结束条件 } // L,R表示起始和终点下标 int p = a[L]; int mark = L; for (int i = L + 1; i <= R; i++) { if (a[i] < p) { cout<<p<<" > "<<a[i]<<endl; cout<<"mark值为"<<mark<<endl; mark++; cout<<"mark值为"<<mark<<endl; swap(a[mark], a[i]); //此时mark表示a[mark]>p,把小的 // 提到前面来 } } swap(a[mark], a[L]); quickSort(a, L, mark - 1); quickSort(a, mark + 1, R); } int main() { vector<int> a = {4,7,3,5,6,2,8,1}; quickSort(a, 0, a.size() - 1); for (int i = 0; i < a.size(); i++) { cout << a[i] << " "; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本