排序算法大总结(持续更新。。。)
2021/7/27 17:07:47
本文主要是介绍排序算法大总结(持续更新。。。),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
想都是问题, 做才是答案
伴随着算法学习的深入,见到的题目变多。
发现自己越来越菜,越深感对基本算法的掌握很是薄弱,昨天补题,知道用二分,二分却打不出。。。白给!!!
这篇博客多总结一下各种排序算法,毕竟很多题也是用到了各种排序方法的思想。。。大部分代码均来自啊哈算法。。
快速排序:
主要思路:选择一个基准数字(一般是第一个数字),设置两个指针分别为 i和j,j从序列后面往前跳动,i从序列前面往后跳动,j遇到一个比基准数字小的数字那么停止,i遇到一个比基准数字大的数字停止,如果i和j不相等,那么将这两个数字交换,直到i和j相等,终止循环,将第i个数字和选择的基准数字交换位置,那么操作之后i前面的数字就全都小于等于它,i后面的数字均大于等于它,那么就找到了这个基准数字应该在的位置,快速排序的每一次都可以说是为了找到这个基准数字应该在的位置。然后递归排序i前面的和i后面序列就可以了。快速排序的时间复杂度并不稳定,最差的情况下为O(N^2),平均时间复杂度为O(logN)。此外还有一点需要注意,那就是指针i和j哪一个先移动,基准值选择在左端的时候要右边的指针先移动,至于原因详https://blog.csdn.net/u013447565/article/details/82079959。
#include<iostream> #include<algorithm> using namespace std; void quick_sort(int *a,int x,int y) { if(x>=y) return; int i=x,j=y; int temp=a[x]; while(i!=j) { while(i<j&&a[j]>=temp) j--; while(i<j&&a[i]<=temp) i++; if(i!=j) { int t=a[i]; a[i]=a[j]; a[j]=t; } } a[x]=a[i]; a[i]=temp; quick_sort(a,x,i-1); quick_sort(a,i+1,y); } int main() { freopen("in.txt","r",stdin); int n,a[100000+10]; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; } quick_sort(a,1,n); for(int i=1;i<=n;i++) { cout<<a[i]<<" "; } return 0; }
堆排序
堆的性质:
堆的形状根完全二叉树的形状一样,都是树的右下角缺少若干叶子结点。
小根堆:树的根结点为最小值,每个父结点都比他的两个子结点要小,堆一般采用数组存储,假设父结点在数组中的编号为i,那么他的左孩子的编号为2*i,右孩子为2*i+1,且父结点的值都比他的两个子结点值小,如果要往堆中添加一个值,那么只需在数组末尾添加,然后将这个数字移动到合适的位置即可,取最小元素的话,那么根节点就是最小元素,这时再添加元素只需要让数组第一个元素为新添加的元素,然后下放到合适的位置即可。在下放的时候要选择选择两个元素中更小那个元素位置进行交换。
具体排序方法
#include<iostream> #include<algorithm> using namespace std; int n,a[100000+10]; void siftdown(int i) { int t,flag=0; while(i*2<=n&&flag==0) { if(a[i]<a[i*2]) t=i*2; else t=i; if(i*2+1<=n&&a[t]<a[i*2+1]) { t=2*i+1; } if(t!=i) { swap(a[t],a[i]); i=t; } else flag=1; } } void creat() { for(int i=n/2;i>=1;i--) { siftdown(i); } return; } void heapsort() { while(n>1) { swap(a[n],a[1]); n--; siftdown(1); } return; } int main() { cin>>n; int temp=n; for(int i=1;i<=n;i++) cin>>a[i]; creat(); heapsort(); for(int i=1;i<=temp;i++) cout<<a[i]<<" "; return 0; }
归并排序:
主要就是分治思想
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> using namespace std; const int maxn=100000+10; const int inf=0x7f7f7f7f; int L[maxn],R[maxn],a[maxn]; int cnt=0; // 执行了多少次比较运算 void merge(int *a,int n,int Left,int mid,int Right) { int n1=mid-Left+1; int n2=Right-mid; for(int i=1;i<=n1;i++) { L[i]=a[Left+i-1]; } for(int i=1;i<=n2;i++) { R[i]=a[mid+i]; } L[n1+1]=inf; R[n2+1]=inf; int i=1; int j=1; for(int p=Left;p<=Right;p++) { cnt++; if(L[i]<=R[j]) { a[p]=L[i++]; } else { a[p]=R[j++]; } } } void mergesort(int *a,int n,int L,int R) { if(R-L>=1) { int mid=(L+R)>>1; mergesort(a,n,L,mid); mergesort(a,n,mid+1,R); merge(a,n,L,mid,R); } } int main() { #ifdef ONLINE_JUDGE #else freopen("in.txt","r",stdin); #endif int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); mergesort(a,n,1,n); for(int i=1;i<=n;i++) { printf("%d ",a[i]); } return 0; }
归并排序求逆序对
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> using namespace std; typedef long long ll; const int maxn = 500000 + 10; const int inf = 0x7f7f7f7f; int L[maxn], R[maxn], a[maxn]; ll merge(int *a, int n, int Left, int mid, int Right) { ll cnt = 0; int n1 = mid - Left + 1; int n2 = Right - mid; for (int i = 1; i <= n1; i++) { L[i] = a[Left + i - 1]; } for (int i = 1; i <= n2; i++) { R[i] = a[mid + i]; } L[n1 + 1] = inf; R[n2 + 1] = inf; int i = 1; int j = 1; for (int p = Left; p <= Right; p++) { if (L[i] <= R[j]) { a[p] = L[i++]; } else { a[p] = R[j++]; cnt += (n1 - i + 1); } } return cnt; } ll mergesort(int *a, int n, int L, int R) { if (R - L >= 1) { int mid = (L + R) >> 1; ll v1 = mergesort(a, n, L, mid); ll v2 = mergesort(a, n, mid + 1, R); ll v3 = merge(a, n, L, mid, R); return v1 + v2 + v3; } else return 0; } int main() { #ifdef ONLINE_JUDGE #else freopen("in.txt", "r", stdin); #endif int n; scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); cout << mergesort(a, n, 1, n) << endl; for (int i = 1; i <= n; i++) { printf("%d ", a[i]); } return 0; }
计数排序
#include<iostream> #include<cstring> #include<algorithm> using namespace std; const int maxn = 100000 + 10; const int max_val = 1000000 + 10; int n, A[maxn], B[maxn], C[max_val]; int main() { #ifdef ONLINE_JUDGE #else freopen("in.txt","r",stdin); #endif memset(C, 0, sizeof C); memset(B, 0, sizeof B); cin >> n; for (int i = 1; i <= n;i++) { cin >> A[i]; C[A[i]]++; } for (int i = 1; i <= max_val+3;i++) C[i]=C[i]+C[i-1]; for (int j = n; j >= 1;j--) { B[C[A[j]]] = A[j]; C[A[j]]--; } for (int i = 1; i <= n; i++) cout << B[i] << " "; return 0; }
冒泡排序
#include<iostream> #include<algorithm> using namespace std; void bubble_sort(int *a,int n) { bool flag = 1; for (int i = 1; flag;i++) { flag = 0; for (int j = n; j >= i + 1;j--) { if(a[j]<a[j-1]) { swap(a[j], a[j - 1]); flag = 1; } } } } int main() { #ifdef ONLINE_JUDGE #else freopen("in.txt","r",stdin); #endif int n, a[100000+10]; cin >> n; for (int i = 1; i <= n;i++) cin >> a[i]; bubble_sort(a, n); for (int i = 1; i <= n;i++) cout<<a[i]<<" "; return 0; }
选择排序
#include<iostream> #include<algorithm> using namespace std; void select_sort(int *a,int n) { for (int i = 1; i <= n;i++) { int minj = i; for (int j = i; j <= n;j++) { if(a[j]<a[minj]) minj = j; } swap(a[i], a[minj]); } } int main() { freopen("in.txt","r",stdin); int n, a[1000]; cin >> n; for (int i = 1; i <= n;i++) cin >> a[i]; select_sort(a, n); for (int i = 1; i <= n;i++) cout<<a[i]<<" "; return 0; }
插入排序
void insert_sort(int a[], int n) { for (int i = 1; i < n; i++) { int v = a[i]; int j = i - 1; while (j >= 0 && a[j] > v) { a[j + 1] = a[j]; j--; } a[j + 1] = v; } } int main() { #ifdef WXY freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); #endif IO; int n; int a[100]; cin >> n; for (int i = 0; i < n; i++) cin >> a[i]; insert_sort(a, n); for (int i = 0; i < n; i++) cout << a[i] << " "; return 0; }
希尔排序 改进的插入排序
#include <iostream> #include <vector> #include <algorithm> using namespace std; const int maxn = 1e6 + 10; int n, cnt, a[maxn]; vector<int> G; void insert_sort(int *a, int n, int g) { for (int i = g + 1; i <= n; i++) { int v = a[i]; int j = i - g; while (j >= 1 && a[j] > v) { a[j + g] = a[j]; j -= g; cnt++; } a[j + g] = v; } } void shell_sort(int *a, int n) { for (int h = 1;;) { if (h > n) break; G.push_back(h); h = 3 * h + 1; } for (int i = G.size() - 1; i >= 0; i--) { insert_sort(a, n, G[i]); } } int main() { #ifdef ONLINE_JUDGE #else freopen("in.txt", "r", stdin); #endif cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; } cnt = 0; shell_sort(a, n); for (int i = 1; i <= n; i++) { cout << a[i] << " "; } return 0; }
这篇关于排序算法大总结(持续更新。。。)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-24怎么修改Kafka的JVM参数?-icode9专业技术文章分享
- 2024-12-23线下车企门店如何实现线上线下融合?
- 2024-12-23鸿蒙Next ArkTS编程规范总结
- 2024-12-23物流团队冬至高效运转,哪款办公软件可助力风险评估?
- 2024-12-23优化库存,提升效率:医药企业如何借助看板软件实现仓库智能化
- 2024-12-23项目管理零负担!轻量化看板工具如何助力团队协作
- 2024-12-23电商活动复盘,为何是团队成长的核心环节?
- 2024-12-23鸿蒙Next ArkTS高性能编程实战
- 2024-12-23数据驱动:电商复盘从基础到进阶!
- 2024-12-23从数据到客户:跨境电商如何通过销售跟踪工具提升营销精准度?