这道题就是练习编写排序算法,可以有多种写法
1、sort库函数
最简单最暴力也是算法中最常用的就是sort函数了,当然这道题我们主要是掌握其它算法,此法就不多赘述
cpp
#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define endl '\n'
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin>>n;
vector<int> a(n);
for(int i=0;i<n;i++)
cin>>a[i];
sort(a.begin(),a.end());
for(int i=0;i<n-1;i++)
cout<<a[i]<<' ';
cout<<a[n-1];
return 0;
}
2、冒泡排序(超时,过不了)
最坏情况是O(N^2^),每轮排好最后一个,拿前面所有的取最大的。
cpp
#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define endl '\n'
void bubblesort(vector<int>& a)
{
int n=a.size();
for(int i=n-1;i>=0;i--)
for(int j=0;j<i;j++)
{
if(a[j]>a[i])
{
int t=a[j];
a[j]=a[i];
a[i]=t;
}
}
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin>>n;
vector<int> a(n);
for(int i=0;i<n;i++)
cin>>a[i];
bubblesort(a);
for(int i=0;i<n-1;i++)
cout<<a[i]<<' ';
cout<<a[n-1];
return 0;
}
3、插入排序(超时)
最坏情况是O(N^2^),前面几个是已经排好的,把新来的插进去,看看当前位置的前一个是不是小于待插入的值,是的话当前位置插入,否则向后移动往前继续找
cpp
#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define endl '\n'
void insertsort(vector<int>& a)
{
int n=a.size();
for(int i=1;i<n;i++)
{
int cur=a[i];int j;
for(j=i;j>0&&a[j-1]>cur;j--)
a[j]=a[j-1];
a[j]=cur;
}
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin>>n;
vector<int> a(n);
for(int i=0;i<n;i++)
cin>>a[i];
insertsort(a);
for(int i=0;i<n-1;i++)
cout<<a[i]<<' ';
cout<<a[n-1];
return 0;
}
4、选择排序(超时)
最坏情况是O(N^2^),先选最小 的下标,再与当前位置交换
cpp
#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define endl '\n'
void shellsort(vector<int>& a)
{
int n=a.size();
for(int i=0;i<n;i++)
{
int cur=i;
for(int j=i+1;j<n;j++)
if(a[j]<a[cur])cur=j;
int t=a[i];
a[i]=a[cur];
a[cur]=t;
}
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin>>n;
vector<int> a(n);
for(int i=0;i<n;i++)
cin>>a[i];
shellsort(a);
for(int i=0;i<n-1;i++)
cout<<a[i]<<' ';
cout<<a[n-1];
return 0;
}
5、堆排序
堆排序的最优时间复杂度、平均时间复杂度、最坏时间复杂度均为 O(nlog n)。所以能通过
cpp
#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define endl '\n'
void sift_down(vector<int> &a,int start,int end)
{// 计算父结点和子结点的下标
int parent=start;
int child=parent*2+1;
while(child<=end)// 子结点下标在范围内才做比较
{// 先比较两个子结点大小,选择最大的
if(child+1<=end&&a[child]<a[child+1])child++;
if(a[parent]>=a[child])return ;
else{ //子结点和孙结点比较
swap(a[parent],a[child]);
parent=child;
child=parent*2+1;
}
}
}
void heapsort(vector<int>& a)
{
int len=a.size();
// 从最后一个节点的父节点开始 sift down 以完成堆化
for(int i=(len-1-1)/2;i>=0;i--)sift_down(a,i,len-1);
// 先将第一个元素和已经排好的元素前一位做交换,再重新调整(刚调整的元素之前的元素),直到排序完毕
for(int i=len-1;i>0;i--)
{
swap(a[0],a[i]);
sift_down(a,0,i-1);
}
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin>>n;
vector<int> a(n);
for(int i=0;i<n;i++)
cin>>a[i];
heapsort(a);
for(int i=0;i<n-1;i++)
cout<<a[i]<<' ';
cout<<a[n-1];
return 0;
}