• C++
  • 通俗易懂的 C++ 中 sort 函数教程

  • @ 2024-12-7 21:32:22

以下是一份通俗易懂的C++中 sort 函数教程:

1. 什么是 sort 函数

sort 函数是C++标准模板库(STL)提供的一个非常方便的排序工具,它可以帮我们快速地对各种序列(比如数组、vector 容器等里面存储的数据)按照一定的规则进行排序。你不用自己去写复杂的排序算法,只要调用这个函数,告诉它要排序的数据范围和排序规则,它就能帮你把数据排好序啦。

2. 包含头文件

要使用 sort 函数,首先得在代码开头包含 <algorithm> 这个头文件,像这样:

#include <algorithm>

因为 sort 函数就是定义在这个头文件里面的哦。

3. 基本使用方法(针对内置类型数组)

假设我们有一个简单的整数数组,想要对它里面的元素进行排序,示例代码如下:

#include <iostream>
#include <algorithm>

int main() {
    int numbers[] = {5, 3, 8, 1, 2};
    int size = sizeof(numbers) / sizeof(numbers[0]);  // 计算数组元素个数

    // 使用sort函数对数组进行排序,第一个参数是要排序的起始地址(也就是数组名,它指向数组第一个元素),
    // 第二个参数是要排序的结束地址(这里指向数组最后一个元素的下一个位置,也就是numbers + size)
    sort(numbers, numbers + size);

    for (int i = 0; i < size; i++) {
        std::cout << numbers[i] << " ";  // 输出排序后的数组元素
    }
    std::cout << std::endl;

    return 0;
}

在这个例子中,sort 函数会把 numbers 数组里的元素按照从小到大的顺序进行排序,最后输出的结果就是 1 2 3 5 8

4. 基本使用方法(针对 vector 容器)

如果是对 vector 容器中的元素进行排序,也是类似的做法哦,看下面的例子:

#include <iostream>
#include <algorithm>
#include <vector>

int main() {
    std::vector<int> vec = {7, 4, 9, 2, 6};

    // 使用sort函数对vector进行排序,第一个参数是vector的起始迭代器(可以理解为指向vector第一个元素的指针一样的东西,通过vec.begin()获取),
    // 第二个参数是vector的结束迭代器(指向vector最后一个元素的下一个位置,通过vec.end()获取)
    sort(vec.begin(), vec.end());

    for (int num : vec) {
        std::cout << num << " ";  // 输出排序后的vector元素
    }
    std::cout << std::endl;

    return 0;
}

这里同样,sort 函数会把 vec 这个 vector 里的元素从小到大排好序,输出结果就是 2 4 6 7 9

5. 指定排序规则(自定义排序)

有时候我们不想按照默认的从小到大(对于数字等内置类型而言)的顺序排序,而是有自己特殊的排序要求,这时候就可以自定义排序规则啦。

我们通过给 sort 函数传入第三个参数来实现自定义排序,这个参数是一个函数(或者叫函数对象,比如仿函数等),它定义了元素之间比较的规则。

例如,我们想对一个整数数组按照从大到小的顺序排序,可以这样写:

#include <iostream>
#include <algorithm>

// 定义一个比较函数,它接收两个整数参数a和b,按照我们想要的规则返回布尔值
// 如果返回true,表示a应该排在b前面,这里我们定义为a大于b时,a排在b前面,也就是实现从大到小排序
bool compare(int a, int b) {
    return a > b;
}

int main() {
    int numbers[] = {5, 3, 8, 1, 2};
    int size = sizeof(numbers) / sizeof(numbers[0]);

    // 使用sort函数对数组进行排序,第三个参数传入我们自定义的compare函数,这样就会按照从大到小的规则排序了
    sort(numbers, numbers + size, compare);

    for (int i = 0; i < size; i++) {
        std::cout << numbers[i] << " ";
    }
    std::cout << std::endl;

    return 0;
}

在这个例子中,因为我们自定义了 compare 函数,告诉 sort 函数按照 a > ba 排在 b 前面的规则来排序,所以最终数组会按照从大到小的顺序排好序,输出结果就是 8 5 3 2 1

同样的道理,对于 vector 容器里的元素,如果要自定义排序规则,也是类似的做法哦,只要把对应的自定义比较函数传入 sort 函数的第三个参数位置就行啦。

6. 一些注意事项

  • sort 函数在大多数情况下排序速度是比较快的,它使用的是一种高效的排序算法(比如快速排序等的优化版本),不过它要求被排序的元素类型要支持比较操作(像数字之间可以比较大小,字符串之间可以按字典序比较等)。
  • 如果要对复杂的数据结构(比如自定义的结构体)进行排序,那就要好好定义好比较规则了,确保比较规则符合你的排序预期哦。

总之,sort 函数是C++中一个很实用的工具,能帮我们轻松地完成各种排序任务,你只要掌握好它的基本使用方法和如何自定义排序规则,就能在实际编程中灵活运用啦。希望这个教程能让你很好地理解和使用 sort 函数哦!

2 条评论

  • @ 2024-12-7 21:34:58

    以下是详细介绍如何对存储自定义结构体的 vector 进行排序的内容,包含多种实现方式及对应的示例代码,方便你理解和掌握这一知识点:

    方式一:使用自定义比较函数(函数形式)

    1. 思路说明

    vector 容器中存储的是自定义结构体类型的数据时,若要对其进行排序,通常需要自定义比较函数来明确排序的规则。这个比较函数接收两个结构体对象作为参数,通过比较结构体中的某些成员变量来确定它们的先后顺序,然后将该比较函数作为参数传递给 sort 函数,从而实现按照自定义规则对 vector 中的结构体元素进行排序。

    2. 示例代码

    以下是一个以存储学生信息结构体的 vector 为例,按照学生成绩进行升序排序的代码示例:

    #include <iostream>
    #include <algorithm>
    #include <vector>
    using namespace std;
    
    // 定义学生结构体,包含姓名和成绩两个成员变量
    struct Student {
        string name;
        int score;
    };
    
    // 自定义比较函数,用于比较两个学生结构体对象的成绩大小,按照成绩升序排序
    bool compareStudents(const Student& s1, const Student& s2) {
        return s1.score < s2.score;
    }
    
    int main() {
        vector<Student> students = {
            {"Alice", 85},
            {"Bob", 90},
            {"Charlie", 80}
        };
    
        // 使用sort函数对students向量进行排序,传入自定义的比较函数compareStudents
        sort(students.begin(), students.end(), compareStudents);
    
        for (const Student& student : students) {
            cout << student.name << " " << student.score << endl;
        }
    
        return 0;
    }
    

    在上述代码中:

    • 首先定义了 Student 结构体,用来表示学生信息,其中有 name(姓名)和 score(成绩)两个成员变量。
    • 接着定义了 compareStudents 函数,它接收两个 const Student& 类型的参数(使用引用可以避免不必要的结构体拷贝,提高效率),在函数内部通过比较两个学生结构体对象的 score 成员变量大小来确定返回值。如果 s1.score 小于 s2.score,则返回 true,表示 s1 应该排在 s2 的前面,这样就确定了按照成绩升序排序的规则。
    • main 函数中,创建了一个 vector<Student> 类型的 students 向量,并初始化了一些学生信息。然后调用 sort 函数,将 students.begin()students.end() 作为要排序的范围,把自定义的 compareStudents 函数作为第三个参数传入,实现了按照成绩升序对学生信息进行排序,并通过循环输出排序后的结果。

    方式二:使用函数对象(仿函数)

    1. 思路说明

    函数对象,也叫仿函数(Functor),本质上是一个类,只不过这个类重载了 operator() 运算符,使得这个类的对象可以像函数一样被调用。我们可以通过定义这样一个函数对象类,在其重载的 operator() 函数中定义结构体元素的比较规则,然后将该函数对象传递给 sort 函数来实现排序。

    2. 示例代码

    以下是使用函数对象按照学生成绩降序对 vector 中的学生结构体进行排序的示例:

    #include <iostream>
    #include <algorithm>
    #include <vector>
    using namespace std;
    
    // 定义学生结构体,包含姓名和成绩两个成员变量
    struct Student {
        string name;
        int score;
    };
    
    // 定义函数对象(仿函数)类,用于比较两个学生结构体对象的成绩大小,按照成绩降序排序
    class CompareStudents {
    public:
        bool operator()(const Student& s1, const Student& s2) const {
            return s1.score > s2.score;
        }
    };
    
    int main() {
        vector<Student> students = {
            {"Alice", 85},
            {"Bob", 90},
            {"Charlie", 80}
        };
    
        // 使用sort函数对students向量进行排序,传入函数对象CompareStudents()
        sort(students.begin(), students.end(), CompareStudents());
    
        for (const Student& student : students) {
            cout << student.name << " " << student.score << endl;
        }
    
        return 0;
    }
    

    在这段代码里:

    • 同样先定义了 Student 结构体来表示学生信息。
    • 然后定义了 CompareStudents 类,它重载了 operator() 运算符,在这个重载函数里,按照 s1.score 大于 s2.score 时返回 true 的规则进行比较,意味着成绩高的学生结构体对象应该排在前面,实现了成绩降序排序的规则。
    • main 函数中,创建 students 向量并初始化学生信息后,调用 sort 函数时,将 CompareStudents 类的临时对象 CompareStudents() 作为第三个参数传入,这样 sort 函数就会依据这个函数对象中定义的规则对 students 向量中的学生结构体进行排序,最后输出排序后的结果。

    方式三:使用C++11及以后的Lambda表达式

    1. 思路说明

    Lambda表达式是C++11引入的一个特性,它允许我们在需要函数的地方直接定义匿名函数,非常方便快捷。对于对 vector 中自定义结构体的排序场景,我们可以使用Lambda表达式在 sort 函数调用的地方直接定义比较规则,而无需单独定义函数或者函数对象。

    2. 示例代码

    以下是以学生结构体为例,使用Lambda表达式按照学生成绩升序对 vector 中的元素进行排序的代码:

    #include <iostream>
    #include <algorithm>
    #include <vector>
    using namespace std;
    
    // 定义学生结构体,包含姓名和成绩两个成员变量
    struct Student {
        string name;
        int score;
    };
    
    int main() {
        vector<Student> students = {
            {"Alice", 85},
            {"Bob", 90},
            {"Charlie", 80}
        };
    
        // 使用Lambda表达式自定义排序规则,按照成绩升序排序
        sort(students.begin(), students.end(), [](const Student& s1, const Student& s2) {
            return s1.score < s2.score;
        });
    
        for (const Student& student : students) {
            cout << student.name << " " << student.score << endl;
        }
    
        return 0;
    }
    

    在这个示例中:

    • 定义好 Student 结构体后,在 main 函数里调用 sort 函数时,第三个参数位置直接使用了Lambda表达式。这个Lambda表达式 [](const Student& s1, const Student& s2) { return s1.score < s2.score; } 接收两个 Student 结构体的引用作为参数,在表达式的函数体中通过比较 s1.scores2.score 的大小来确定返回值,实现了按照成绩升序排序的规则。sort 函数依据这个规则对 students 向量中的学生结构体元素进行排序,最后输出排序后的结果。

    以上就是对存储自定义结构体的 vector 进行排序的几种常见方式,你可以根据具体的需求和编程习惯选择合适的方法来实现相应的排序功能。

    • @ 2024-12-7 21:33:43

      以下是几种常见的对 vector 容器进行排序的示例代码,涵盖了不同数据类型以及使用默认排序规则和自定义排序规则的情况,代码都使用C++语言编写,并添加了详细注释方便你理解:

      1. 对存储整数的 vector 使用默认排序规则(从小到大)

      #include <iostream>
      #include <algorithm>
      #include <vector>
      using namespace std;
      
      int main() {
          vector<int> numbers = {5, 3, 8, 1, 2};
          // 使用sort函数对vector进行排序,sort函数的前两个参数指定排序范围
          // begin()指向vector的第一个元素,end()指向vector最后一个元素的下一个位置,即整个vector的范围
          sort(numbers.begin(), numbers.end());
      
          for (int num : numbers) {
              cout << num << " ";
          }
          cout << endl;
      
          return 0;
      }
      

      在上述代码中,vector 容器 numbers 中存储了一些整数,通过调用 sort 函数并传入 numbers.begin()numbers.end(),就可以按照默认的从小到大的顺序对 numbers 中的整数进行排序,最终输出排好序后的整数序列。

      2. 对存储字符串的 vector 使用默认排序规则(按字典序从小到大)

      #include <iostream>
      #include <algorithm>
      #include <vector>
      using namespace std;
      
      int main() {
          vector<string> words = {"apple", "banana", "cherry", "date"};
          sort(words.begin(), words.end());
      
          for (string word : words) {
              cout << word << " ";
          }
          cout << endl;
      
          return 0;
      }
      

      这里的 vector 容器 words 存放了一些字符串,调用 sort 函数后,它会按照字符串的字典序(默认的比较方式)对 words 中的字符串进行排序,然后输出排序后的字符串序列。

      3. 对存储自定义结构体的 vector 使用自定义排序规则

      假设我们有一个表示学生的结构体,里面包含学生的姓名和成绩,现在想根据成绩对学生信息进行排序,示例代码如下:

      #include <iostream>
      #include <algorithm>
      #include <vector>
      using namespace std;
      
      // 定义学生结构体
      struct Student {
          string name;
          int score;
      };
      
      // 自定义比较函数,用于按照学生成绩从小到大排序
      bool compareByScore(const Student& s1, const Student& s2) {
          return s1.score < s2.score;
      }
      
      int main() {
          vector<Student> students = {
              {"Alice", 85},
              {"Bob", 90},
              {"Charlie", 80}
          };
      
          // 使用sort函数对students这个vector进行排序,传入自定义的比较函数compareByScore
          sort(students.begin(), students.end(), compareByScore);
      
          for (const Student& student : students) {
              cout << student.name << " " << student.score << endl;
          }
      
          return 0;
      }
      

      在这段代码中:

      • 首先定义了 Student 结构体来表示学生信息,包含姓名和成绩两个成员变量。
      • 接着定义了 compareByScore 自定义比较函数,它接收两个 Student 结构体的引用,按照成绩进行比较,返回成绩小的学生结构体应该排在前面的布尔值。
      • 然后创建了一个存储 Student 结构体的 vector 容器 students,并初始化了一些学生信息。
      • 最后调用 sort 函数,传入 students.begin()students.end() 以及自定义的比较函数 compareByScore,这样就可以根据成绩对 students 中的学生信息进行从小到大的排序,并输出排序后的结果。

      4. 对存储自定义结构体的 vector 使用C++11及以后的Lambda表达式自定义排序规则(同样以学生结构体为例)

      #include <iostream>
      #include <algorithm>
      #include <vector>
      using namespace std;
      
      // 定义学生结构体
      struct Student {
          string name;
          int score;
      };
      
      int main() {
          vector<Student> students = {
              {"Alice", 85},
              {"Bob", 90},
              {"Charlie", 80}
          };
      
          // 使用Lambda表达式自定义排序规则,按照成绩从大到小排序
          sort(students.begin(), students.end(), [](const Student& s1, const Student& s2) {
              return s1.score > s2.score;
          });
      
          for (const Student& student : students) {
              cout << student.name << " " << student.score << endl;
          }
      
          return 0;
      }
      

      在这个示例中,利用了C++11引入的Lambda表达式来定义排序规则,在 sort 函数的第三个参数位置直接传入Lambda表达式,表达式中定义了按照学生成绩从大到小排序的比较逻辑,实现了对 students 向量中存储的学生结构体信息的自定义排序并输出结果。

      这些示例展示了在不同情况下对 vector 容器进行排序的常见用法,你可以根据实际需求选择合适的方式来对 vector 中的元素进行排序哦。

      • 1