排序问题
Posted monty1
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序问题相关的知识,希望对你有一定的参考价值。
第十章、排序
一、各个排序的时间复杂度:
二、概念:
1、稳定排序:若记录序列中有两个或两个以上关键字相等的记录:Ki=kj(i!=j),排序后的记录序列仍然是Ri先于Rj,则称排序方法是稳定的,否则是不稳定的。
否则则是不稳定排序。
2、内部排序:待排序的记录书不太多:所有的记录都能存放在内存中进行排序,称为内部排序。
3、外部排序:待排序列的记录数太多:所有的记录不可能存放在内存中,排序过程中必须在内、外存之间进行数据交换,这样的排序称为外部排序。
三、插入排序:
1、基本操作:
将一个记录插入到已排好序的有序表中,从而得到一个新的、记录数增一的有序表。
其时间复杂度为o(n*n).
2、代码:
#include<cstdio> #include<iostream> using namespace std; int a[100]={}; int main(){ int n=0; int b=0; while(cin>>a[n++]); n=n-1; // for(int i=0;i<n;i++){ // cout<<a[i]<<" "; // } // cout<<"\\n"; for(int i=1;i<n;i++){ int key=a[i]; int j=i-1; for(;j>=0&&a[j]>key;j--){ a[j+1]=a[j]; } a[j+1]=key; } for(int i=0;i<n;i++){ cout<<a[i]<<" "; } cout<<"\\n"; } //测试用例 //3 65 43 32 2 1 43 54
四、希尔排序:
1、排序思想:
利用增量进行排序。
五、快速排序:
1、排序思想:通过选定一个参照,将待排序列分为独立的两部分,其中一部分记录的关键字均比另一部分小,再分别对这两部分记录进行下一次排序,已达到整个序列有序。
2、代码:
//归并排序 #include<iostream> using namespace std; int partition(int* a,int p,int r){ int i=p-1; int j=p; int key=a[r]; for(;j<r;j++){ if(a[j]<=key){ i=i+1; int temp=a[i]; a[i]=a[j]; a[j]=temp; } } a[r]=a[i+1]; a[i+1]=key; return (i+1); } void quick_sort(int* a,int p,int r){ if(p<r){ int q; q=partition(a,p,r); quick_sort(a,p,q-1); quick_sort(a,q+1,r); } } int main(){ int n; int a[100]={}; cin>>n; for(int i=0;i<n;i++){ cin>>a[i]; } quick_sort(a,0,n-1); for(int i=0;i<n;i++) cout<<a[i]<<" "; }
六、选择排序:
1、基本操作:
通过n-i次操作,从n-i+1个记录中选取关键字最小的记录,然后和第i个记录交换。
2、算法复杂度:
o(n*n)
七、归并排序:
1、只将两个或者两个以上的有序序列合并成一个有序序列。若采用现象表,其时间复杂度为o(m+n).
2、代码:
1 #include<iostream> 2 using namespace std; 3 int a[100]={}; 4 #define Max 100000 5 void merge(int* a,int p,int q,int ri){ 6 int l=q-p+1; 7 int r=ri-q; 8 int left[l+1]={}; 9 int right[r+1]={}; 10 for(int i=0;i<=l;i++){ 11 left[i]=a[i+p]; 12 } 13 for(int j=0;j<r;j++){ 14 right[j]=a[j+q+1]; 15 } 16 left[l]=Max; 17 right[r]=Max; 18 int i=0; 19 int j=0; 20 for(int k=p;k<=ri;k++){ 21 if(left[i]<=right[j]){ 22 a[k]=left[i++]; 23 }else{ 24 a[k]=right[j++]; 25 } 26 } 27 28 } 29 void merge_sort(int* a,int p,int r){ 30 if(p<r){ 31 int q; 32 q=(int)((p+r)/2); 33 //cout<<q; 34 merge_sort(a,p,q); 35 merge_sort(a,q+1,r); 36 merge(a,p,q,r); 37 } 38 } 39 int main(){ 40 int n; 41 cin>>n; 42 for(int i=0;i<n;i++){ 43 cin>>a[i]; 44 } 45 merge_sort(a,0,n-1); 46 for(int i=0;i<n;i++){ 47 cout<<a[i]<<" "; 48 } 49 cout<<"\\n"; 50 }
八、冒泡排序:
1、思想:每次将相邻的两个进行比较,直到每次将最大的冒泡到最底部。(我认为主要需要和选择排序进行区分,选择排序需要每次和n-i+1个数比较,而冒泡排序是和相邻元素比较)。
2、代码:
#include<stdio.h> int maopao(int *a,int n){ for(int i=0;i<n;i++){ for(int j=0;j<n-i-1;j++){ if(a[j]>a[j+1]){ int tmp=a[j+1]; a[j+1]=a[j]; a[j]=tmp; } } } } int main(){ int i=0; int a[100]; while(scanf("%d",&a[i++])==1); i=i-1; maopao(a,i); for(int j=0;j<i;j++){ printf("%d ",a[j]); } printf("\\n"); }
以上是关于排序问题的主要内容,如果未能解决你的问题,请参考以下文章
Realm和RecyclerView项目排序和自动ViewPager片段通信
ElasticSearch学习问题记录——Invalid shift value in prefixCoded bytes (is encoded value really an INT?)(代码片段