排序

简单介绍了冒泡排序、选择排序、插入排序、快速排序、堆排序和C++中sort函数的实现及复杂度。

一、冒泡排序

方法一
void Bubble_Sort(int a[],int len) {
	for (int i = 0;i < len - 1;i++) {
		for (int j = 0;j < len - 1 - i;j++) {
			if (a[j] > a[j + 1]) {
				int temp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = temp;
			}
		}
	}
}
方法二(优化)

设置一个标志,每次外层循环时判断整个数组是否已经排好序,是则终止循环,结束。

void Bubble_Sort_2(int a[], int len) {
	int flag = 0;
	for (int i = 0;i < len - 1;i++) {
		for (int j = 0;j < len - 1 - i;j++) {
			if (a[j] > a[j + 1]) {
				int temp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = temp;
				flag = 1;
			}
		}
		if (flag == 0) {
			return;
		}
	}
}
复杂度

时间复杂度: O ( N 2 ) O(N^2) O(N2)
空间复杂度: O ( 1 ) O(1) O(1)

二、选择排序

基本思想:为每一个位置选择未排序的序列中的最小(或最大)的元素并交换。

void Select_Sort(int a[],int len) {
	for (int i = 0;i < len - 1;i++) {
		int min = a[i];   //记录最小值
		int min_index = i;  //记录最小值对应的索引
		for (int j = i + 1;j < len;j++) { //找到未排序序列中最小的值
			if (min > a[j]) {
				min = a[j];
				min_index = j;
			}
		}
		if (i != min_index) {   //如果最小的不是自己则交换
			int temp = a[i];
			a[i] = min;
			a[min_index] = temp;
		}
	}
}
复杂度

时间复杂度: O ( N 2 ) O(N^2) O(N2)

空间复杂度: O ( 1 ) O(1) O(1)

三、插入排序

基本思想:将有序序列末端的元素插入到有序序列中相应的位置。

void Insert_Sort(int a[],int len) {
	for (int i = 0;i < len;i++) {
		for (int j = i;j > 0;j--) {
			if (a[j] < a[j - 1]) { //交换元素
				int temp = a[j];
				a[j] = a[j - 1];
				a[j -1] = temp;
			}
			else
				break;
		}
	 }
}
复杂度

时间复杂度: O ( N 2 ) O(N^2) O(N2)

空间复杂度: O ( 1 ) O(1) O(1)

四、快速排序

void Quick_Sort(int a[],int left,int right) {
	if (left >= right)return;
	int i = left;
	int j = right;
	int k = a[i];      //以最左边的元素为基准
	while (i < j) {
		while (i < j&&a[j] >= k)  //找右边的元素中比基准元素小的元素
		{
			j--;
		}
		a[i] = a[j];
		while (i < j&&a[i] <= k)  //找左边的元素中比基准元素大的元素
		{
			i++;
		}
		a[j] = a[i];
	}
	a[i] = k;
	Quick_Sort(a, left, i - 1);
	Quick_Sort(a,i+1,right);
}
复杂度

时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
空间复杂度: O ( l o g n ) O(logn) O(logn)

五、堆排序

为了减少代码量,该算法使用STL库实现堆排序。

  • make_heap(_First, _Last, _Comp):
    建立堆,当_Comp为less时,建立最大堆,为greater时,建立最小堆。
  • push_heap (_First, _Last):
    向堆中添加数据。要先在容器(如vector)中添加,再调用push_heap()。
  • pop_heap(_First, _Last):
    在堆中删除数据。调用完pop_heap()后,再删除容器中的数据。
  • sort_heap(_First, _Last):堆排序。
void print_sort(vector<int> a) {   //打印结果的函数
	for (vector<int>::iterator it = a.begin();it != a.end();it++) {
		cout << *it << " ";
	}
	cout << endl;
}
int main() {
	int a[10] = { 33,2,1,6,4,2,1,5,18,0 };
	vector<int> b(a,a+10);
	make_heap(b.begin(),b.end(),greater<int>());//创建最小堆
	sort_heap(b.begin(),b.end(),greater<int>());//排序
	print_sort(b);
}

排序结果:
排序结果

往堆中添加数据,先在容器中添加,再调用push_heap():

b.push_back(99);   //b是一个vector
push_heap(b.begin(), b.end(), less<int>());

再次排序结果:
在这里插入图片描述
删除堆中的数据,先调用pop_heap(),再删除容器中的数据:

pop_heap(b.begin(), b.end(), greater<int>());
b.pop_back();

再次排序结果:
在这里插入图片描述
可以发现0被pop掉了。

复杂度

时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
空间复杂度: O ( 1 ) O(1) O(1)

六、C++中sort函数

sort函数的头文件为#include<algorithm>。
假设有一个数组int a[4]={1,2,3,4},sort(a,a+4)可将a中的元素从小到大进行排序,除此之外,sort函数第三个参数也可以是一个比较函数,下面以PAT中
1015 德才论为例进行解释。

1015 德才论 (25 分)
宋代史学家司马光在《资治通鉴》中有一段著名的“德才论”:“是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之小人。凡取人之术,苟不得圣人,君子而与之,与其得小人,不若得愚人。”
现给出一批考生的德才分数,请根据司马光的理论给出录取排名。

输入格式:

输入第一行给出 3 个正整数,分别为:N(≤10
​5
​​ ),即考生总数;L(≥60),为录取最低分数线,即德分和才分均不低于 L 的考生才有资格被考虑录取;H(<100),为优先录取线——德分和才分均不低于此线的被定义为“才德全尽”,此类考生按德才总分从高到低排序;才分不到但德分到线的一类考生属于“德胜才”,也按总分排序,但排在第一类考生之后;德才分均低于 H,但是德分不低于才分的考生属于“才德兼亡”但尚有“德胜才”者,按总分排序,但排在第二类考生之后;其他达到最低线 L 的考生也按总分排序,但排在第三类考生之后。
随后 N 行,每行给出一位考生的信息,包括:准考证号 德分 才分,其中准考证号为 8 位整数,德才分为区间 [0, 100] 内的整数。数字间以空格分隔。

输出格式:

输出第一行首先给出达到最低分数线的考生人数 M,随后 M 行,每行按照输入格式输出一位考生的信息,考生按输入中说明的规则从高到低排序。当某类考生中有多人总分相同时,按其德分降序排列;若德分也并列,则按准考证号的升序输出。

我们用一个结构体对学生进行存储:

struct Student{
    char num[10];  //学号
    int d,c,s;  //德才和总分;
    int flag;   //学生所在类别
}stu[100010];

现要对若干学生根据题目中的要求对学生进行排序,我们按照题目要求编写一个比较函数:

bool cmp(Student a,Student b){
    if(a.flag!=b.flag){
        return a.flag<b.flag; //类别小的在前面
    }
    else if(a.s!=b.s){
        return a.s>b.s;  //类别一样时总分大的在前面
    }
    else if(a.d!=b.d){
        return a.d>b.d; //总分相同时德分大的在前面
    }
    else{
        return strcmp(a.num,b.num)<0; //德分一样时准考证小的在前面
    }
}

然后我们就可以对stu数组中的若干学生使用sort函数进行排序了:

sort(stu,stu+N,cmp);

这样输出结果就可以了,别忘了先引用头文件#include<algorithm>。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cxp_001

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值