C++ Sort函数详解

前言: sort()函数是<alogrithm>库下的一个函数,sort()函数是不稳定的,如果需要稳定的排序算法,可以转为使用stable_sort()stable_sort的实现是基于归并排序的,它的时间复杂度为O(nlogn),一般情况下会比基于快排的sort()稍慢。

1. sort函数调用的两种方式

方法1(默认) void sort (RandomAccessIterator first, RandomAccessIterator last);
方式2 (自定义) void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
  • 默认: 两个参数first,last,将 [first, last) 区间内元素 升序 排列。【注意区间为左闭右开】
  • 自定义排序: 需用户指定排序规则Compare comp,将 [first, last)区间内的元素按照用户指定的顺序排列。

举例:

/*
Description:
jlh很喜欢吃水果,苹果是他最喜欢的,其次是梨。
他天天想着吃水果,竟然感动了女娲大神,
女娲大神给了他n个篮子,让他选择其中的m个(m<=n)个篮子。
每个篮子里有a个苹果和b个梨。请你们帮jlh选择篮子吧。
Input:
输入一个t(t<=10),表示有t组测试数据,
再输入n和m(0=<m<=n<=100000),
接下来的n行,输入a和b表示苹果和梨的数量。
Output:
按jlh选择的顺序
(先选苹果多的,苹果数量相同选梨多的,两者相同选序号小的)
篮子的序号(1-n),m个数用空格隔开。
Sample Input:
2
2 1
2 0
1 4

3 2
3 4
2 6
3 5
Sample Output:
1
3 1
 */
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
using namespace std;
/**
 * 自定义篮子
 */
class basket{
    
    
public:
    int apple;    // 苹果数量
    int pear;     // 梨的数量
    int id;       // id
};

/**
 * 自定义比较函数
 * @param a 篮子a
 * @param b 篮子b
 * @return
 * 若a,b中苹果数量不等,返回a, b 篮子中苹果数量;a>b返回true
 * 若a,b中梨的数量不等,返回a, b 篮子中梨数量;a>b返回true
 * 否则比较id小的篮子;a<b返回true
 */
bool compareFruitAlgorithm(const basket a, const  basket b) {
    
    
    if (a.apple != b.apple)
        return a.apple > b.apple;   // 若a,b中苹果数量不等,返回a, b 篮子中苹果数量;a>b返回true
    else if (a.pear != b.pear)
        return a.pear > b.pear;     // 若a,b中梨的数量不等,返回a, b 篮子中梨数量;a>b返回true
    else return a.id < b.id;            // 否则比较id小的篮子;a<b返回true
}

int main() {
    
    
    // Input:  输入一个t(t<=10),表示有t组测试数据,再输入n和m(0=<m<=n<=100000),接下来的n行,输入a和b表示苹果和梨的数量。
    // Output: 按jlh选择的顺序(先选苹果多的,苹果数量相同选梨多的,两者相同选序号小的)篮子的序号(1-n),m个数用空格隔开。
    int t;
    cin >> t;
    while(t--) {
    
        // while(0)就是false,便跳出循环。
        int n, m;   // 共有n个篮子,其中选m个篮子
        cin >> n >> m;
        vector<basket> baskets(n); // 建立n个篮子
        // 装入
        for (int i=0; i<n; ++i) {
    
    
            cin >> baskets[i].apple >> baskets[i].pear; // 装入苹果和梨的数量
            baskets[i].id=i+1;
        }

        // 排序
        sort(baskets.begin(), baskets.end(), compareFruitAlgorithm);
        //      vector.begin()就是指向第一个元素:[0]位置
        //      vector.end()指向最后一个元素的后一个元素位置。

        // 输出
        //      这里要注意,题目给的示例中,输出每一排最后一个元素之后是没有空格的,所以要分类讨论
        //          1.不是这一排最后一个要输出的元素,输出id之后再带上" ";
        //          2.是这一排最后一个元素,仅仅输出这个id,并且换行。
        for (int i=0; i<m; ++i) {
    
    
            if (i != m-1)
            	printf("%d ", baskets[i].id);   // 不是这一排最后一个要输出的元素,输出id之后再带上" "
            else printf("%d\n", baskets[i].id); // 是这一排最后一个元素,仅仅输出这个id,并且换行。
        }
    }
}

2. sort函数使用场景

由于在排序过程中涉及到元素交换等操作,所以sort函数仅支持可随机访问的容器,如数组, string、vector、deque等。

3.sort函数排序原理

​sort()并非只是普通的快速排序,除了对普通的快速排序进行优化,它还结合了插入排序和堆排序。根据不同的数量级别以及不同情况,能自动选用合适的排序方法。当数据量较大时采用快速排序,分段递归。一旦分段后的数据量小于某个阀值,为避免递归调用带来过大的额外负荷,便会改用插入排序。而如果递归层次过深,有出现最坏情况的倾向,还会改用堆排序。

​所以无论元素初始时为何种状态,sort()的平均排序复杂度为均为O(nlog2(n)) ,具有不错的的性能,在刷算法题时,可以直接使用sort()来对数据进行排序,而不需手动编写排序函数。

4. 自定义comp函数返回true或false作用

bool cmp(int num1, int num2) {
    
    	// 实现降序排列
    return num1 > num2;	// num1大于num2时返回true,否则返回false
}

自定义函数返回值为bool类型

  • 若返回true,则表示num1 与num2应该交换顺序;
  • 若返回false, 则num1 与num2 保持原有顺序;

猜你喜欢

转载自blog.csdn.net/weixin_45827203/article/details/129686427