初见 | 数据排序

目前未添加归并排序 因为我不会

为什么要对数据进行排序?

举个简单的例子

2020国总统大选有n位竞争者
他们分别是A,B,C,D,E,F,G,H,I,J......
他们的票数为710,273,123,654,354,725,443,353,204......
而这个国家又很特别,要选选票第n小的人当

如果我们直接在这些无序的数据中找......
如果人很多的话.....
这是很麻烦的

如果按照排序,那就会变得简单点
虽然人工排序也不是个简单活
但是我们有电脑和C++

一本通上给的解释是这样的:


非常充分的解释

那么
知道为什么要排序之后,就可以来看排序的具体方法

选择排序

这里我用从小到大排来举例子
(如果没有特殊说明后面都是从小到大排)

基本思路

从未排序的数列中找到最小的依次和最前面的交换

基本步骤

  1. 读入数据存到a数组中
  2. a[m+1]a[n]范围内找到一个最小的元素,和a[m]交换
  3. 重复2m从0到n-1

标准程序

因为(懒)最近也没用上所以就一本通贴过来的
最近没用上的后面都直接贴了

冒泡排序

基本思路和步骤

比较相邻的两个数,如果逆序就交换

标准程序

改进程序

对于有些特殊的数据,不一定要排n-1次,那我们就可以判断一下是否进行了交换,如果没有,那就说明排序已经结束了

插入排序

基本思路

在未排序的数据中依次找到它应该在已排序数据中的位置

标准程序

桶排序

基本思路和步骤

以空间换时间,设计有限个桶,将待排序的值放入其对应的桶中

标准程序

#include <iostream>
#include <cstring>
using namespace std;
int x[101];
int main()
{
	int n,k;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>k;x[k]++;
	}
	for(int i=0;i<=100;i++)
	{
		while(x[i]>0)
		{
			cout<<i<<" ";
			x[i]--;
		}
	}
	cout<<endl;
	return 0;
}//虽然没用上但是感觉应该打一打

快速排序

基本思路和步骤

这是利用二分冒泡排序进行了改进
先对数据进行分割
规定其中的一部分比另外一部分的元素小,根据这个就可以对剩下的数据继续排序

程序

//快排 
#include<iostream>
using namespace std;
int a[1000001],n;
void qsort(int l,int r)
{
	int i,j,mid;
	i=l;j=r;
	mid=a[(l+r)/2];
	do
	{
		while (a[i]<mid) i++;
		while (a[j]>mid) j--;
		if(i<=j)
		{
			swap(a[i],a[j]);
			i++;j--;
		}
	}
	while(i<=j);
	if(l<j) qsort(l,j);
	if(i<r) qsort(i,r);
} 
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	qsort(1,n);
	for(int i=1;i<=n;i++)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;
	return 0;
}

sort函数

sort在algorithm里面

使用方法

sort(起始位置,结束位置,排列函数)
下面用一个题来解释
一本通T1183 病人排序

【题目描述】

病人登记看病,编写一个程序,将登记的病人按照以下原则排出看病的先后顺序:

1.老年人(年龄 >= 60岁)比非老年人优先看病。
2.老年人按年龄从大到小的顺序看病,年龄相同的按登记的先后顺序排序。
3.非老年人按登记的先后顺序看病。

【输入】
第1行,输入一个小于100的正整数,表示病人的个数;
后面按照病人登记的先后顺序,每行输入一个病人的信息,包括:一个长度小于10的字符串表示病人的ID(每个病人的ID各不相同且只含数字和字母),一个整数表示病人的年龄,中间用单个空格隔开。

【输出】
按排好的看病顺序输出病人的ID,每行一个。

【输入样例】
5
021075 40
004003 15
010158 67
021033 75
102012 30

【输出样例】
021033
010158
021075
004003
102012

这个题一看就是对比较函数的考察,毕竟这么多条件。
那上述条件用函数来表示就是

int cmp(p a,p b)
{
      return 
      (a.age>=60&&b.age<60)
      ||(a.age>=60&&b.age>=60&&a.age>b.age)
      ||(a.age>=60&&b.age>=60&&a.age==b.age&&a.n<b.n)
      ||(a.age<60&&b.age<60&&a.n<b.n);
}

也就是满足上述条件才进行排序

题目剩下的也没有什么了,就直接放码

#include <iostream>
#include <algorithm>
using namespace std;
struct p
{
	string id;
	int age;
	int n;	
};
int cmp(p a,p b)
{
	return (a.age>=60&&b.age<60)||(a.age>=60&&b.age>=60&&a.age>b.age)||(a.age>=60&&b.age>=60&&a.age==b.age&&a.n<b.n)||(a.age<60&&b.age<60&&a.n<b.n);
}
p l[101];
int main()
{
	int n;cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>l[i].id>>l[i].age;
		l[i].n=i;
	}
	sort(l+1,l+1+n,cmp);
	for(int i=1;i<=n;i++)
	{
		cout<<l[i].id<<endl;
	}
	return 0;
}

以上是基本的排序方法,总之就是数据排序会举几个具体的题目

End

这篇水,不计数

posted @ 2021-02-04 17:33  HerikoDeltana  阅读(95)  评论(0编辑  收藏  举报