七种基础排序算法代码总汇
1、冒泡排序
算法详解参考:https://mp.weixin.qq.com/s/wO11PDZSM5pQ0DfbQjKRQA
#include <iostream> #include <vector> using namespace std; void swap(vector<int> &arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } void BubbleSort(vector<int> &arr) { int flag = 1; // flag标记是否继续比较元素大小,这里赋值为1是为了进入循环 for(int i = 1; i < arr.size() && flag; i++) { flag = 0; // 初始化为0 for(int j = arr.size() - 1; j >= i; j--) { if(arr[j] > arr[j+1]) // 升序 { swap(arr, j+1, j); flag = 1; // 不在比较元素时 flag = 1,进入下一次循环 } } } } int main() { vector<int> arr = {0, 5, 3, 4, 6, 2}; BubbleSort(arr); for(int i = 0; i < arr.size(); i++) cout << arr[i] << " "; cout << endl; return 0; } // 冒泡法排序总时间复杂度 O(n^2)
2、简单选择排序
算法详解参考:https://mp.weixin.qq.com/s/dGfh2t7xhg0wMM_DcYP1Cw
#include <iostream> #include <vector> using namespace std; void swap(vector<int> &arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } void SelectSort(vector<int> &arr) { int min; for(int i = 1; i < arr.size(); i++) { min = i; for(int j = i+1; j <= arr.size(); j++) { if(arr[min] > arr[j]) min = j; } if(i != min) swap(arr, i, min); } } int main() { vector<int> arr = {0, 5, 3, 4, 6, 2}; SelectSort(arr); for(int i = 0; i < arr.size(); i++) cout << arr[i] << " "; cout << endl; return 0; } // 简单选择排序总时间复杂度 O(n^2) // 性能略优于冒泡
3、直接插入排序
算法详解参考:https://mp.weixin.qq.com/s/McqFXkXucSZldjU46t5cdw
#include <iostream> #include <vector> using std::cout; using std::endl; using std::vector; void swap(vector<int> &arr, int i, int j) { int a = arr[i]; arr[i] = arr[j]; arr[j] = a; } void InsertSort(vector<int> &arr) { for(int i = 1; i < arr.size(); i++) { int j = i; while (j > 0 && arr[j] < arr[j-1]) { swap(arr, j, j-1); j--; } } } int main() { vector<int> arr = {0, 5, 3, 4, 6, 2}; InsertSort(arr); for(int i = 0; i < arr.size(); i++) cout << arr[i] << " "; cout << endl; return 0; } // 直接插入排序总时间复杂度 O(n^2) // 性能优于冒泡和简单选择排序
4、希尔排序
算法详解参考:https://mp.weixin.qq.com/s/b9-dkpAhWJYshuSs5cwnOw
#include <iostream> #include <vector> using namespace std; void ShellSort(vector<int> &arr) { int increment = arr.size(); // 希尔排序的增量初始化 while (increment > 1) { increment /= 2; // 增量折半 for(int i = 0; i < increment; i++) { for(int j = i+increment; j < arr.size(); j = j+increment) { int temp = arr[j]; int k = 0; for(k = j-increment; k >= 0 && arr[k] > temp; k = k-increment) arr[k + increment] = arr[k]; // 由于 k 的值发生了更新,但是在此循环结束之前索引 j 是没有发生变化的,所以 k + increment != j(第一次循环时 k+increment = j) arr[k + increment] = temp; } } } } int main() { vector<int> arr = {5, 8, 6, 3, 9, 2, 1, 7}; ShellSort(arr); for(int i = 0; i < arr.size(); i++) cout << arr[i] << " "; cout << endl; return 0; } // 希尔排序是不稳定排序 // Hibbard增量序列:最坏时间复杂度 O(n^(3/2)) // Sedgewick增量序列:最坏时间复杂度 O(n^(4/3))
5、堆排序
算法详解参考:https://mp.weixin.qq.com/s/8Bid1naBLtEjPoP-R4HkBg
#include <iostream> #include <vector> using namespace std; // 大顶堆调整 void adjustHeap(vector<int> &arr, int i, int length) { int temp = arr[i]; // 先取出当前元素 i for(int k = i*2 + 1; k < length; k = k*2 + 1) // 从 i 结点左子节点开始,也就是 2i+1 处开始 { if(k+1 < length && arr[k] < arr[k+1]) // 如果左子节点小于右子节点,k指向右子节点 k++; if(arr[k] > temp) // 如果子节点大于父节点,将子节点赋值给父节点(不用交换) { arr[i] = arr[k]; i = k; } else break; } arr[i] = temp; // 将 temp 值放到最终位置 } // 元素交换 void swap(vector<int> &arr, int i, int j) { int a = arr[i]; arr[i] = arr[j]; arr[j] = a; } void heapSort(vector<int> &arr) { // 构建大顶堆 for(int i = arr.size()/2 - 1; i >= 0; i--) // 从第一个非叶子结点从上至下,从右到左调整结构 adjustHeap(arr, i, arr.size()); // 调整堆结构加交换堆顶元素与末尾元素 for(int j = arr.size() - 1; j > 0; j--) { swap(arr, 0, j); // 将堆顶元素与末尾元素进行交换 adjustHeap(arr, 0, j); // 重新调整堆结构 } } int main() { vector<int> arr = {5, 8, 6, 3, 9, 2, 1, 7}; heapSort(arr); for(int i = 0; i < arr.size(); i++) cout << arr[i] << " "; cout << endl; return 0; } // 堆排序整体时间复杂度 O(nlogn)
6、归并排序
算法详解参考:https://mp.weixin.qq.com/s/885uGVhlffWAxjgIEW-TiA
#include <iostream> #include <vector> using namespace std; void merge(vector<int> &arr, int start, int mid, int end) { // 开辟额外大集合,设置指针 vector<int> tempArray((end - start + 1), 0); int p1 = start, p2 = mid+1, p = 0; // 比较两个小集合的元素,依次放入大集合 while(p1 <= mid && p2 <= end) { if(arr[p1] <= arr[p2]) tempArray[p++] = arr[p1++]; else tempArray[p++] = arr[p2++]; } // 左(右)侧小集合有剩余,依次放入大集合尾部 while(p1 <= mid) tempArray[p++] = arr[p1++]; while(p2 <= end) tempArray[p++] = arr[p2++]; // 把大集合元素赋值回原数组 for(int i = 0; i < tempArray.size(); i++) arr[i+start] = tempArray[i]; } void mergeSort(vector<int> &arr, int start, int end) { if(start < end) { // 折半成两个小集合,分别进行递归 int mid = (start + end) / 2; mergeSort(arr, start, mid); mergeSort(arr, mid+1, end); // 把两个有序小集合归并成一个大集合 merge(arr, start, mid, end); } } int main() { vector<int> arr = {5, 8, 6, 3, 9, 2, 1, 7}; mergeSort(arr, 0, arr.size() - 1); for(int i = 0; i < arr.size(); i++) cout << arr[i] << " "; cout << endl; return 0; } // 总时间复杂度 O(nlogn)
7、快速排序
算法详解参考:https://zhuanlan.zhihu.com/p/93129029
// 快排递归实现 #include <iostream> using namespace std; void quickSort(int *arr, int begin, int end) { if(begin < end) { int temp = arr[begin]; int i = begin; int j = end; while(i < j) { while(i < j && arr[j] > temp) j--; arr[i] = arr[j]; while(i < j && arr[i] <= temp) i++; arr[j] = arr[i]; } arr[i] = temp; // 递归排序基准数两边子集 quickSort(arr, begin, i-1); quickSort(arr, i+1, end); } else return; } int main() { int num[10] = {23, 14, 5, 7, 29, 50, 11, 33, 10, 8}; cout << "排序前: " << endl; for(int i = 0; i < 10; i++) cout << num[i] << " "; cout << endl; quickSort(num, 0, 9); cout << "排序后: " << endl; for(int i = 0; i < 10; i++) cout << num[i] << " "; cout << endl; return 0; } // 快速排序时间复杂度 O(nlogN)
分类:
Algorithms学习
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现