算法(三) 排序
1.插入排序
#include<iostream>
#include<cstdio>
using namespace std;
#define N 5
int a[N];//有序数组
int main ( ) {
int i, k, x;
printf("Please input %d numbers:\n",N);
for (i=0; i<N; i++) {
scanf ("%d", &x);
for ( k=i; k>0; k-- ) { /* 从后向前比较 */
if ( a[k-1] > x ) //x前面的数比它大
a[k]=a[k-1]; /* 将大数向后移动*/
else break; /* 找到插入的位置,退出 */
}
a[k] = x; /* 完成插入操作 */
}
for (i=0; i<N; i++)
printf("%d ", a[i]);
return 0;
}
2.快速排序
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[100055];
void qsort(int l,int r)//快排函数
{
int i=l; //左边
int j=r; //右边
int x=a[(l+r)/2]; //取基准数
while(i<=j) //要使<x的数都在左边,>x的数都在右边
{
while(a[j]>x) //满足的就略过
j--;
while(a[i]<x)
i++;
if(i<=j)
{
swap(a[i],a[j]); //不满足,就两个交换
i++; //同时继续移动
j--;
}
}
if(j-l>=1) //递归过程
qsort(l,j);
if(r-i>=1)
qsort(i,r);
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
qsort(1,n);
for(int j=1;j<=n;j++)
cout<<a[j]<<" ";
return 0;
}
3.STL中的Sort
sort 在 STL 库中是排序函数,有时冒泡、选择等 O(n2)O(n2) 算法会超时时,我们可以使用 STL 中的快速排序函数 O(n log n)O(n log n) 完成排序
sort 在 algorithm 库里面,原型如下:
template
void sort ( RandomAccessIterator first, RandomAccessIterator last );
template <class RandomAccessIterator, class Compare>
void sort ( RandomAccessIterator first, RandomAccessIterator last, Compare comp );
我们会发现 sort 有两种形式一个有三个参数,一个有两个参数,我们先讲讲两个参数的吧!
sort 的前两个参数是起始地址和中止地址
如:sort(a,a+n) 表示对 a[0] … a[n-1] 排序
代码如下:
#include <algorithm>
#include <cstdio>
using namespace std;
int main() {
int n,a[1001];
scanf("%d",&n);
for (int i = 1;i <= n;i++) scanf("%d",&a[i]);
sort(a+1,a+n+1); //对a[1] ... a[n] 排序
for (int i = 1;i <= n;i++) printf("%d",a[i]);
return 0'
}
这样是默认升序的,那如果是降序呢?
这样,我们就要用到第三个参数,第三个参数是一个比较函数
bool cmp(int a,int b) { return a > b; }
这个就是降序排序的比较函数,意思是:
是 a > b 时为true,就不交换,a < b 时为 false,交换
然后我们调用 sort(a+1,a+n+1,cmp) 就可以对 a 数组进行排序了
还可以调用 greater 和 less 进行升/降序排序,其实就是一个帮你写好的函数
int a[11],n;
scanf("%d",&n);
for (int i = 1;i <= n;i++) scanf("%d",&a[i]);
sort(a+1,a+n+1,greater<int>()); //升序
sort(a+1,a+n+1,less<int>()); //降序,注意尖括号内写的是排序的数组类型
sort 也能对结构体排序,如:
#include <algorithm>
#include <cstdio>
using namespace std;
struct Node {
int x,y;
} p[1001];
int n;
bool cmp(Node a,Node b) {
if (a.x != b.x) return a.x < b.x;
return a.y < b.y;
}
int main() {
scanf("%d",&n);
for (int i = 1;i <= n;i++) scanf("%d%d",&p[i].x,&p[i].y);
sort(p+1,p+n+1,cmp);
for (int i = 1;i <= n;i++) scanf("%d %d\n",p[i].x,p[i].y);
return 0;
}
题2021
题目描述
请将坐标x,y,z依照以下规则排序:
x为第一关键字,当x相同时,依照y(第二关键字)大小来排序,相同时,依照z大小来排序(第三关键字)
给出了若干坐标,和一个数k,请输出第k大的坐标。
输入
排序(第三关键字)
给出了若干坐标,和一个数k,请输出第k大的坐标。
输入数据:
一个数字n(n<10000),表示坐标的个数
接下来n行,每行包含三个数xi,yi,zi表示坐标值
接下来一个数k(k<n)。
输出
三个数,表示相应的坐标
样例输入
4
1 3 5
1 3 6
2 3 5
6 5 1
2
样例输出
1 3 6
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct weizhi
{
int x;
int y;
int z;
}a[100055]; //开辟一个结构体数组
bool cmp(weizhi i,weizhi j) //bool类型,控制sort是否进行排序
{
if(i.x==j.x) //相等要优先判断,再考虑小于情况
{
return i.y<j.y;
if(i.y==j.y)
return i.z<j.z;
}
return i.x<j.x;
}
int main()
{
int n,i,k;
cin>>n;
for(i=0;i<n;i++) //输入
cin>>a[i].x>>a[i].y>>a[i].z;
//sort函数 排序区间为前开后闭,注意范围
//对结构体数组进行排序,cmp为参数,简单而言,可说明为排序规则
sort(a,a+n,cmp);
cin>>k; //输出的位置
cout<<a[k-1].x<<" "<<a[k-1].y<<" "<<a[k-1].z<<endl;
return 0;
}