<1>冒泡排序
冒泡排序的思想是每次将最大的一下一下运到最右边,然后将最右边这个确定下来,再来确定第二大的,再确定第三大的…由于排序过程中,数字像冒泡泡一样从左往右换过去,故名冒泡排序。时间复杂度为O(n^2)。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3 + 9;
int a[N];
int main(){
int n;cin >> n; //输入3
for(int i = 1;i <= n;i++) cin>>a[i]; //输入1 3 2
for(int i = 1;i <= n;i++){
for(int j = 1;j <= n-i;j++){
if(a[j] > a[j + 1]) swap(a[j],a[j+1]);
}
}
for(int i = 1;i <= n;++i) cout<<a[i]<<' '; //输出1 2 3
return 0;
}
<2>选择排序
选择排序思想和冒泡排序类似,是每次找出最大的然后直接放到右边对应位置,然后将最右边这个确定下来(而不是一个一个地交换过去)。对于数组a[],具体来说,每次确定操作(假设当前要确定的是i位置)就是从左往右扫描,计算出最大元素的下标max_i,最后执行一次swap(a[max_i],a[i])将两项交换即可。和冒泡排序的区别就是,冒泡排序需要每次都交换,而选择排序则是确定了某个数第几大直接交换,时间复杂度和冒泡排序一样,都是O(n^2),但是交换的次数减少了。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+9;
int a[N];
int main(){
int n;cin>>n;
for(int i = 1;i <= n;i++) cin>>a[i];
//i表示当前要确定的位置
for(int i = n;i >= 1;--i){
int max_i = 1;
for(int j = 1;j <= i;++j){
if(a[j] > a[max_i]) max_i = j;
}
swap(a[max_i],a[i]);
}
for(int i = 1;i <= n;i++) cout<<a[i]<<' ';
return 0;
}
#*这里的j的范围是[1,i],而在冒泡排序中j的范围是[1,i-1]。
<3>插入排序
插入排序是一种简单直观的排序算法,其基本思想是将待排序的元素逐个插入到已排序序列的合适位置中,使得已排序序列逐渐扩大,从而逐步构建有序序列,最终完全得到完全有序的序列。时间复杂度为O(n^2)。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+9;
int a[N];
int main(){
int n;cin>>n;
for(int i = 1;i <= n;i++) cin>>a[i];
for(int i = 2;i <= n;++i){
int val = a[i],j;
for(j = i;j > 1 && val < a[j-1];j--) a[j] = a[j-1];
a[j] = val;
}
for(int i = 1;i <= n;i++) cout<<a[i]<<' ';
return 0;
}
<4>快速排序
快速排序是一种基于分治法的排序方法,基本思想是,先选定pivot中心轴,再将大于pivot的数字放在pivot的右边,小于pivot的数字放在pivot的左边,然后分别对左右子序列重复前三步操作,得到一个升序的序列。快速排序拥有更好的时间复杂度O(nlogn),且不需要额外空间。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+9;
int a[N];
int partitions(int a[],int low,int high){
int pivot = a[low];
while(low < high){
while(low < high && a[high] >= pivot) high--;
a[low] = a[high];
while(low < high && a[low] <= pivot) low++;
a[high] = a[low];
}
a[low] = pivot;// or a[high] = pivot;
return low;
}
void quickSort(int a[],int low,int high){
if(low < high){
int pivotpos = partitions(a,low,high);
quickSort(a,low,pivotpos-1);
quickSort(a,pivotpos+1,high);
}
}
int main(){
int n;cin>>n;
int low = 1,high = n;
for(int i = 1;i <= n;i++) cin>>a[i];
quickSort(a,low,high);
for(int i = 1;i <= n;i++) cout<<a[i]<<' ';
return 0;
}
<5>归并排序
归并排序和快速排序类似,也是基于分治法的排序方法。原理是将一个数组分为两个子数组,将子数组向下递归的排序后(当数组中仅有一个元素值无需再排序了,直接返回),得到两个有序数组,然后进行O(n)的合并,最终合并成有序的原数组。归并排序拥有较好的时间复杂度O(nlogn),但需要额外的空间用于合并数组。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+9;
int a[N],b[N];
//归并
void merge(int a[],int low,int mid,int high){
int i,j,k;
for(k = low;k <= high;++k){
b[k] = a[k];
}
for(i = low,j = mid+1,k = i;i <= mid && j <= high;k++){
if(b[i] <= b[j]) a[k] = b[i++]; // 将较小值复制到a中
else a[k] = b[j++];
}
while(i <= mid) a[k++] = b[i++];
while(j <= high) a[k++] = b[j++];
}
void mergeSort(int a[],int low,int high){
if(low < high){
int mid = (low + high) / 2;
mergeSort(a,low,mid);
mergeSort(a,mid+1,high);
merge(a,low,mid,high);
}
}
int main(){
int n;cin>>n;
for(int i = 1;i <= n;i++) cin>>a[i];
mergeSort(a,1,n);
for(int i = 1;i <= n;++i) cout<<a[i]<<' ';
return 0;
}