八大基本排序
一、时间复杂度与空间复杂度
二、原理与代码
1、直接插入排序
1)原理:从序列第二个数开始,将一个数插入到前面已经排序好的序列,记录数加一,以此类推。
2)代码:
//直接插入 void insertSort(int a[],int n) { int temp; for (int i = 1; i < n; i++) { for (int j = i; j > 0; j--) { if (a[j] < a[j - 1]) { temp = a[j]; a[j] = a[j - 1]; a[j - 1] = temp; } } } }
2、冒泡排序
1)原理:
(1)比较第一个数和第二个数的大小,若前一个大于后一个,则交换;
(2)接着比较第二个和第三个,以此类推,一轮比较完,得到最大的数放在最后面;
(3)接着下一轮比较,重复(1)(2)操作,直到最后全部排序完
2)代码:
//冒泡排序 void bubbleSort(int a[], int n) { int temp; for (int i = 0; i < n; i++) { for (int j = 0; j <n-1; j++) { if (a[j] > a[j + 1]) { temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } } } }
3、直接选择排序
1)原理:找到最小的数放到序列的最前面,与冒泡排序相比,大大减少了交换次序
2)代码:
//直接选择排序 void sort8(int a[], int n) { for (int i = n-1; i > 0; i--) {for (int j = 0; j <= i; j++) { if (a[j] > a[0]) {
swap(a[j],a[0]); } }
swap(a[0],a[i]); } }
4、堆排序
1)原理:将序列转换为一颗完全二叉树,通过结点与孩子结点的大小比较,最后转换为小顶堆(或者大顶堆)
假设序列为n的序列组,具体步骤如下:
(1)取中间数mid=n/2,从序号为mid的数开始,比较该结点与孩子结点的大小,若孩子结点比父结点大,则交换;
(2)记录数减一,重复(1)(2)操作,直到得到大顶堆;
(3)交换第一个数和最后一个数,序列组长度减一,重复(1)(2)操作,直到全部排序完成。
2)代码:
//堆排序 void heapSort(int a[],int n) { int temp; for (int i = n; i > 0; i--) { pileSort(a,i); temp = a[0]; a[0] = a[i-1]; a[i-1] = temp; } } void pileSort(int a[],int n) { int mid = n / 2; int temp; for (int i = mid; i >= 0; i--) { if (a[i] < a[2 * i + 1] && 2 * i + 1 < n) { temp = a[i]; a[i] = a[2 * i + 1]; a[2 * i + 1] = temp; } if (a[i] < a[2 * i + 2] && 2 * i + 2 < n) { temp = a[i]; a[i] = a[2 * i + 2]; a[2 * i + 2] = temp; } } }
5、希尔排序
1)原理:希尔排序又名缩小增量排序,直接插入排序在序列大部分有序的情况下,效率会非常高,希尔排序则是为了实现这一点,该排序是先把序列划分为若干个子序列,使用直接排序进行排序,最后序列基本有序后再对整个序列进行一次直接插入排序。
2)代码:
//希尔 void shellSort(int a[], int n) { int length = n; while (length > 1) { length = length / 2; for (int i = 0; i < length; i++) { for (int j = i + length; j < n; j = j + length) { int temp = a[j]; int k; for (k = j - length; k >= 0 && a[k] > temp; k = k - length) { a[k + length] = a[k]; } a[k + length] = temp; } } } }
6、快速排序
1)原理:每次操作都找出数据索引位置,形成左边的数都比这个数小,右边的数都比这个数大,再把左边的序列重复该操作,右边的序列也重复该操作。
2)代码:
void quickSort(int a[], int left,int right) { int mid; if (left < right) { mid = partition(a,left,right); quickSort(a, left, mid-1); quickSort(a, mid+1, right); } } int partition(int a[],int left,int right) { int data = a[left]; while (left < right) { while (a[right] >= data && left < right) { right--; } a[left] = a[right]; while (a[left] <= data && left < right) { left++; } a[right] = a[left]; } a[left] = data; return left; }
7、基数排序
1)原理:桶排序的拓展,将整数按位数切分为不同的数字,按每个数的位数比较。
2)代码:
//基排 void baseSort(int a[], int n,int bit) { int c[10][50]; int num = 1; for (int i = 1; i <= bit; i++) { int b[10] = { 0,0,0,0,0,0,0,0,0,0 }; if(i!=1) num = num * 10; for (int j = 0; j < n; j++) { int temp = (a[j] / num) %10; c[temp][b[temp]] = a[j]; b[temp]++; } int m = 0; for (int k = 0; k < 10; k++) { if (b[k] > 0) { int end = b[k]; for (int t = 0; t < end; t++) { a[m] = c[k][t]; m++; } } } } }
8、归并排序
1)原理:该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。
2)代码:
//归并排序 void mergeSort(int a[], int left, int right,int b[]) { int mid = ((right - left) >> 1) + left; if (right <= left) { return; } mergeSort(a, left, mid, b); mergeSort(a, mid + 1, right, b); merge(a,left,right,b); } void merge(int a[],int left,int right,int b[]) { int mid = ((right - left) >> 1) + left; int i = left, j = mid+1,k = left; while (i <= mid && j <= right) b[k++] = a[i] < a[j] ? a[i++] : a[j++]; while (i <= mid) b[k++] = a[i++]; while (j <= right) b[k++] = a[j++]; for (int m = left; m <= right; m++) { a[m] = b[m]; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)