C++标准模板库(STL):algorithm头文件的常用函数之sort()函数

sort()—排序函数

顾名思义,sort就是用来排序的函数,它根据具体情形使用不同的排序算法,效率很高。一般来说,不推荐C语言中的qsort函数,原因是qsort用起来比较麻烦,涉及很多指针的操作。而且sort在实现中规避了经典快速排序中可能出现的会导致实际复杂度退化到O(n2)的极端情况

1. 如何使用sort排序

sort函数的使用必须加上头文件“#include<algorithm>”和"using namespace std;",其使用的方式如下:

sort(首元素的地址(必填), 尾元素地址的下一个地址(必填), 比较函数(非必填));

可以看到,sort的参数有三个,其中前两个是必填的,而比较函数则可以根据需要填写,如果不写比较函数,则默认对前面给出的区间进行递增排序。

可以先从示例入手:

 1 #include<stdio.h>
 2 #include<algorithm>
 3 using namespace std;
 4 int main() {
 5     int a[6] = {9, 4, 2, 5, 6, -1};
 6     //将a[0]~a[3]从小到大排序
 7     sort(a, a + 4);
 8     for(int i = 0; i < 6; i++) {
 9         printf("%d ", a[i]);
10     }
11     printf("\n");
12     //将a[0]~a[5]从小到大排序
13     sort(a, a + 6);
14     for(int i = 0; i < 6; i++) {
15         printf("%d ", a[i]);
16     }
17     return 0;
18 }

运行之后可以得到下面的结果, 可以试着理解一下(特别注意理解“尾元素地址的下一个地址”)。输出结果:

2 4 5 9 5 -1
-1 2 4 5 6 9

又如,对double型数组排序

 1 #include<stdio.h>
 2 #include<algorithm>
 3 ?
 4 using namespace std;
 5 int main() {
 6     double a[] = {1.4, -2.1, 9};
 7     sort(a, a + 3);
 8     for(int i = 0; i < 3; i++) {
 9         printf("%.1f ", a[i]);
10     }
11     return 0;
12 }

输出结果:

-2.1 1.4 9

再如,对char型数组排序(默认为字典序):

#include<stdio.h>
#include<algorithm>
using namespace std;
int main() {
    char c[] = {‘T‘, ‘W‘, ‘A‘, ‘K‘};
    sort(c, c + 4);
    for(int i = 0; i < 4; i++) {
        printf("%c ", c[i]);
    }
}

输出结果:

A K T W 

关于sort的排序原理细节咱不讨论,但是应当知道,如果需要对序列进行排序,那么序列中的元素一定要有可比性,因此需要制定排序规则来建立这种可比性。特别是像结构体,本身没有大小关系我,需要人为制定比较的规则。sort的第三个可选参数就是compare函数(一般写作cmp函数),用来实现这个规则

2. 如何实现比较函数

下面介绍对基本数据类型、结构体类型、STL容器进行自定义规则排序时cmp的写法。

(1)基本数据类型数组的排序

若比较函数不填,则默认按照从小到大的顺序排序。下面是对int型数组的排序:

#include<stdio.h>
#include<algorithm>
using namespace std;
int main() {
    int a[5] = {3, 1, 4, 2};
    sort(a, a + 4);
    for(int i = 0; i < 4; i++) {
        printf("%d ", a[i]);
    }
    return 0;
}

输出结果:

1 2 3 4 

如果想要从大到小来排序,则要使用比较函数cmp来“告诉”sort何时要交换元素(让元素的大小笔记哦啊关系反过来)。还是上面那个例子,这里比较的元素是int类型,可以这样写:

#include<stdio.h>
#include<algorithm>
using namespace std;
bool cmp(int a, int b) {
    return a > b;   //可以理解为当a > b 时把a放在b前面
}
int main() {
    int a[] = {3, 1, 4, 2};
    sort(a, a + 4, cmp);
    for(int i = 0; i < 4; i++) {
        printf("%d ", a[i]);    //输出 4 3 2 1
    }
    return 0;
}

输出结果:

4 3 2 1

这样就可以让数值较大的元素放在前面,也就达到了从大到小排序的要求。

同样的,对double型数组从大到小的代码如下:

#include<stdio.h>
#include<algorithm>
using namespace std;
bool cmp(double a, double b) {
    return a > b;   //同样是a > b
}
int main() {
    double a[] = {1.4, -2.1, 9};
    sort(a, a + 3, cmp);
    for(int i = 0; i < 3; i++) {
        printf("%.1f ", a[i]);
    }
    return 0;
}

输出结果:

9.0 1.4 -2.1

对char型数组从大到小排序的代码如下:

#include<stdio.h>
#include<algorithm>
using namespace std;
bool cmp(char a, char b) {
    return a > b;   //同样是 a > b
}
int main() {
    char c[] = {‘T‘, ‘W‘, ‘A‘, ‘K‘};
    sort(c, c + 4, cmp);
    for(int i = 0; i < 4; i++) {
        printf("%c", c[i]);
    }
    return 0;
}

输出结果:

WTKA

记忆方法: 如果要把数据从小到大排列,那么就用"<",因为"a<b"就是左小右大;如果要把数据从大到小排列,那么就用">",因为"a>b"就是左大右小。而当不确定或者忘记时,不妨两种都试一下,就会知道该用哪种了。

(2)结构体数组的排序

现在定义了如下的结构体:

 struct node { int x, y; }ssd[10]; 

如果想将ssd数组按照x从大到小排序(即进行一级排序),那么可以这样写cmp函数:

 bool cmp(node a, node b) { return a.x>b.x; } 

实例如下:

#include<stdio.h>
#include<algorithm>
using namespace std;
struct node {
    int x, y;
}ssd[10];
bool cmp(node a, node b) {
    return a.x > b.x;   //按x值从大到小对结构体数组排序
}
int main() {
    ssd[0].x = 2;   //{2, 2}
    ssd[0].y = 2;
    ssd[1].x = 1;   //{1, 3}
    ssd[1].y = 3;
    ssd[2].x = 3;   //{3, 1}
    ssd[2].y = 1;
    sort(ssd, ssd + 3, cmp);    //排序
    for(int i = 0; i < 3; i++) {
        printf("%d %d\n", ssd[i].x, ssd[i].y);
    }
    return 0;
}

输出结果:

3 12 21 3

而如果想先按x从小打到排序,但当x相等的情况下,按照y的大小从小到大来排序(即进行二级排序),那么cmp的写法是:

 bool cmp(node a, node b) { if(a.x != b.x) return a.x > b.x else return a.y < b.y } 

这里的cmp函数首先判断结构体内的x元素是否相等,如果不相等,则直接按照x的大小来排序;否则,比较两个结构体中y的大小,并按y从小到大排序。

示例如下:

#include<stdio.h>
#include<algorithm>
using namespace std;
struct node {
    int x, y;
}ssd[10];
bool cmp(node a, node b) {
    if(a.x != b.x) return a.x > b.x;    //x不等时按x从大到小排序
    else return a.y < b.y;  //x相等时按y从小到大排序
}
int main() {
    ssd[0].x = 2;   //{2, 2}
    ssd[0].y = 2;
    ssd[1].x = 1;   //{1, 3}
    ssd[1].y = 3;
    ssd[2].x = 3;   //{3, 1}
    ssd[2].y = 1;
    sort(ssd, ssd + 3, cmp);    //排序
    for(int i = 0; i < 3; i++) {
        printf("%d %d\n", ssd[i].x, ssd[i].y);
    }
    return 0;
}

输出结果:

2 12 21 3

(3)容器的排序

在STL标准容器中,只有vector、string、deque是可以使用sort的。这是因为像set、map这种容器是用红黑树实现的(了解即可),元素本身有序,故不允许使用sort排序。

#include<stdio.h>
#include<algorithm>
using namespace std;
bool cmp(int a, int b) {    //因为vector中的元素为int型,因此仍然是int的比较
    return a > b;
}
int main() {
    vector<int> vi;
    vi.push_back(3);
    vi.push_back(1);
    vi.push_back(2);
    sort(vi.begin(), vi.end(), cmp);    //对整个vector排序
    for(int i = 0; i < 3; i++) {
        printf("%d ", vi[i]);
    }
    return 0;
}

输出结果:

3 2 1

再来看string的排序:

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
int main() {
    string str[3] = {"bbbb", "cc", "aaa"};
    sort(str, str + 3); //将string型数组按字典序从小到大到输出
    for(int i = 0; i < 3; i++) {
        cout<<str[i]<<endl;
    }
    return 0;
}

上面的代码输出如下:

aaabbbbcc

如果上面这个例子,需要按字符串长度从小到大排序,那么可以这样写:

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
bool cmp(string str1, string str2) {
    return str1.length() < str2.length();   //按string的长度从小到大排序
}
int main() {
    string str[3] = {"bbbb", "cc", "aaa"};
    sort(str, str + 3, cmp);
    for(int i = 0; i < 3; i++) {
        cout<<str[i]<<endl;
    }
    return 0;
}

输出结果:

ccaaabbbb

原文地址:https://www.cnblogs.com/dreamcoding/p/10341727.html

时间: 2024-08-07 15:59:36

C++标准模板库(STL):algorithm头文件的常用函数之sort()函数的相关文章

八、C++ 标准模板库-STL概述

C++ 标准模板库-STL概述 一.基本概念 1.1 泛型程序设计 C++ 语言的核心优势之一就是便于软件的重用,重用在两个方面有体现: 面向对象的思想:继承和多态,标准类库 泛型程序设计(generic programming) 的思想: 模板机制,以及标准模板库 STL 简单地说就是使用模板的程序设计法.将一些常用的数据结构(比如链表,数组,二叉树)和算法(比如排序,查找)写成模板,以后则不论数据结构里放的是什么对象,算法针对什么样的对象,则都不必重新实现数据结构,重新编写算法. 标准模板库

标准模板库--STL

标准模板库STL 1.泛型程序设计 C++ 语言的核心优势之一就是便于软件的重用 C++中有两个方面体现重用: 1.面向对象的思想:继承和多态,标准类库 2.泛型程序设计(generic programming) 的思想: 模板机制,以及标准模板库STL 简单地说就是使用模板的程序设计法. 将一些常用的数据结构(比如链表,数组,二叉树)和算法(比如排序,查找)写成模板,以后则不论数据结构里放的是什么对象,算法针对什么样的对象,则都不必重新实现数据结构,重新编写算法.标准模板库 (Standard

PKU C++程序设计实习 学习笔记6 标准模板库STL

标准模板库STL 8.1 STL概述 1.泛型程序设计 C++ 语言的核心优势之一就是便于软件的重用 C++中有两个方面体现重用:1.面向对象的思想:继承和多态,标准类库  2.泛型程序设计(generic programming) 的思想: 模板机制,以及标准模板库 STL 简单地说就是使用模板的程序设计法. 将一些常用的数据结构(比如链表,数组,二叉树)和算法(比如排序,查找)写成模板,以后则不论数据结构里放的是什么对象,算法针对什么样的对象,则都不必重新实现数据结构,重新编写算法. 标准模

标准模板库(STL)学习探究之vector容器

标准模板库(STL)学习探究之vector容器  C++ Vectors vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据.为了可以使用vector,必须在你的头文件中包含下面的代码:#include <vector>构造函数. Vectors 包含着一系列连续存储的元素,其行为和数组类

C++的标准模板库STL中实现的数据结构之顺序表vector的分析与使用

摘要 本文主要借助对C++的标准模板库STL中实现的数据结构的学习和使用来加深对数据结构的理解.即联系数据结构的理论分析和详细的应用实现(STL),本文是系列总结的第一篇,主要针对线性表中的顺序表(动态数组)STL vector进行分析和总结. 引言 因为前段时间对台大的机器学习基石和技法课程进行了学习,发如今详细的实现中经常涉及到各种类型的数据结构,比方线性表.二叉树.图等,在使用这些数据结构时感到有些吃力.主要是对一些主要的数据结构理解的不够.所以趁着暑假假期.近期一段时间总会抽出时间复习一

C++ 标准模板库STL 队列 queue 使用方法与应用介绍

C++ 标准模板库STL 队列 queue 使用方法与应用介绍 queue queue模板类的定义在<queue>头文件中. 与stack模板类很相似,queue模板类也需要两个模板参数,一个是元素类型,一个容器类型,元素类型是必要的,容器类型是可选的,默认为deque类型. 定义queue对象的示例代码如下: queue<int> q1; queue<double> q2; queue的基本操作有: 入队,如例:q.push(x); 将x接到队列的末端. 出队,如例:

实验8 标准模板库STL

一.实验目的与要求: 了解标准模板库STL中的容器.迭代器.函数对象和算法等基本概念. 掌握STL,并能应用STL解决实际问题. 二.实验过程: 完成实验8标准模板库STL中练习题,见:http://acm.hpu.edu.cn/contest.php?cid=1020,密码c++08,共有5道题.将答题过程简单记录到实验过程中. 将答题结果写到实验结果中,并根据答题结果进行分析.反思,将其写到实验分析中,并写上实验时间.

C++笔记(6):标准模板库STL:容器、迭代器和算法

STL(Standard Template Library)是C++标准库的一部分.STL的代码从广义上讲分为三类:容器.迭代器和算法. 1.容器 2.迭代器 3.算法  -------------------------------------------------------------------------------------------------------------------------- 1.容器 顺序容器容器是特定类型对象的集合.顺序容器为程序员提供控制元素存储和访问

C++的标准模板库(STL)简介

STL(Standard Template Library,标准模板库)是C++对泛型编程思想的实现,最早是惠普实验室开发的.在被引入C++之前该技术就已经存在了很长的一段时间.后来STL成为ANSI/ISO C++标准的一部分.各个C++厂商也有各自相应的模板库,这些库效率可能很高,但可移植性不一定好. 在C++标准中,STL被组织为下面的17个头文件:<algorithm>.<deque>.<functional>.<iterator>.<arra

【c++】标准模板库STL入门简介与常见用法

一.STL简介 1.什么是STL STL(Standard Template Library)标准模板库,主要由容器.迭代器.算法.函数对象.内存分配器和适配器六大部分组成.STL已是标准C++的一部分,使用STL开发系统可以提高开发效率. 2.容器(Containers) 容器类是可以包含其它对象的模板类,如向量类(vector).链表类(list).双向队列类(deque).集合类(set)和映射类(map)等.其中vector.list.deque为序列式容器,set.map为关联式容器.