常用排序算法记录(C++实现)
排序过程中,对尚未确定最终位置的元素进行一遍处理,叫做“一趟”
内部排序的比较
插入排序
思想: 如果自己前面的元素比自己大,那么开始比较更前面的元素,放在合适的位置。
void insertSort(int a[],int n){
int i, j;
for(i = 1; i < n; ++i){
if(a[i] < a[i - 1]){
int temp = a[i];
// 依次查看前面是不是还有比自己大的元素
for(j = i - 1; j >= 0 && a[j] > temp; --j){
a[j + 1] = a[j];
} // for
a[j + 1] = temp;
} // if
} // for
}
void insertBinarySort(int a[],int n){
int i, j;
for(i = 1; i < n; ++i){
if(a[i] < a[i - 1]){
int temp = i;
int low = 0;
int high = i - 1;
// 二分查找
while(low <= high){
int mid = (high - low) / 2 + low;
// 为了保证插入排序稳定性,在相等时候low = mid + 1
if(a[mid] == temp || a[mid] < temp){
low = mid + 1;
}else{
high = mid - 1;
} // else
} // while
for(j = i - 1; j >= low; --j){
a[j + 1] = a[j];
}
a[low] = temp;
}
}
}
希尔排序
思想: 设定间隔d,将间隔为d的元素分为一小组,然后每次进行组内排序,并且递减d的值
冒泡排序
思想: 依次比较相邻的两个元素,如果逆序,则将他们交换交换
快速排序
思想: 采用“分治”的策略,选定一个元素为枢轴,然后所有比枢轴大的在右边,比枢轴小的在左边。
注:408原题中说,对所有尚未确定最终位置的所有元素进行一遍处理称为“一趟”排序,因此一次“划分”一趟排序。一次划分可以确定一个元素的最终位置,而一趟排序也许可以确定多个元素的最终位置。
#include <cstdio>
#include <algorithm>
int a[10];
using namespace std;
int getMid(int start, int end){
int mid = start + (end - start) / 2;
int Sum = a[start] + a[mid] + a[end];
int Max = max(max(a[start], a[mid]), a[end - 1]);
int Min = min(min(a[start], a[mid]), a[end - 1]);
int Mid = Sum - Max - Min;
if(Mid == a[start])
return start;
else if(Mid == a[mid])
return mid;
else
return end - 1;
}
int partition(int start, int end){
int pos = getMid(start, end);
int key = a[pos];
swap(a[pos], a[end - 1]);
int i = start, j = end - 1;
while(i < j){
// 两个指针轮流遍历
for(; i < j; ++i){
if(a[i] > key){
a[j] = a[i];
break;
} // if
} // for
for(; i < j; --j){
if(a[j] < key){
a[i] = a[j];
break;
} // if
} // for
} // while
a[i] = key;
return i;
}
void quickSort(int start, int end){
if(start + 1 < end){
int pos = partition(start, end);
quickSort(start, pos);
quickSort(pos + 1, end);
}
}
int main(){
int n;
scanf("%d", &n);
for(int i = 0; i < n; ++i)
scanf("%d", a + i);
quickSort(0, n);
for(int i = 0; i < n; ++i)
printf("%d%c", a[i], " \n"[i == n - 1]);
return 0;
}
简单选择排序
思想: 每次找出待排序元素中最小的一个,与第一个交换
void selectSort(int a[], int n){
for(int i = 0; i < n - 1; ++i){
int min = i;
for(int j = i + 1; j < n; ++j){
if(a[j] < a[min]){
min = j;
}
if(min != i){
swap(a[i], a[min]);
}
} // for
}
}
堆排序
堆的数组形式即是该二叉树的
建堆
依次取数组
排序
思想: 先建立堆,然后取堆顶元素与最后一个待排序元素进行交换,再调整堆,重复此过程,直到进行完
时间复杂度:
空间复杂度:
是不稳定排序
归并排序
思想: 采用“分治的方法”,将待排序数组细分成各个只有两个元素的数组,然后不断进行有序合并以完成排序
公式:
对于2路归并排序中,待排序元素为
对于
void myMerge(int a[], int left, int right){
int mid = left + (right - left) / 2;
int nl = mid - left, nr = right - mid;
int l[nl], r[nr];
for(int i = 0; i < nl; ++i)
l[i] = a[left + i];
for(int i = 0; i < nr; ++i)
r[i] = a[mid + i];
int k = left, i = 0, j = 0;
while(i < nl && j < nr && k < right){
if(l[i] <= r[j]){
a[k] = l[i];
++i, ++k;
}else{
a[k] = r[j];
++j, ++k;
} // else
} // while
while(i < nl && k < right){
a[k] = l[i];
(void) (++i), ++k;
} // while
while(j < nr && k < right){
a[k] = r[j];
(void) (++j), ++k;
} // while
}
void mergeSort(int *a, int left, int right){
if(left + 1 < right){
int mid = left + (right - left) / 2;
mergeSort(a, left, mid);
mergeSort(a, mid, right);
myMerge(a, left, right);
}
}
基数排序(桶排序)
思想: 首先按照最低位大小进行排序,然后再按照次高位进行排序,如此往复,直到最高位排序完成(即
假定需要
时间复杂度:
空间复杂度:
【推荐】国内首个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 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」