你所不知道的sort方法

本文详细解析了JavaScript sort方法的底层原理,为何会导致默认排序错误,并提供了自定义比较器的解决方案。通过实例演示了如何使用函数实现正确排序数组。

说到快速排序,我们第一想到的一定是sort方法,但是,不要着急,在使用之前我们必须要了解sort方法到底是如何排序的。

例如: 我们对数组进行排序,我想我们的答案都是正确的。

let arr = [1,3,5,2,4]
arr.sort() // [1, 2, 3, 4, 5]

再看下面这一组

let arr = [5,22,8,36,1]
console.log(arr.sort()) //[1, 22, 36, 5, 8]

结果是不是和你预期的不一样呢,知其然,不知其所以然,所以今天刨根问底,一探究竟

为什么第二组排序会出现问题呢,原因如下:

1.js中的sort方法并不是按照我们数学中的1-10...,这样去依次排序的。

2.sort(默认升序),它会将排序的元素转为字符串,所以第二组的数组转变为 ['5','25','8','36','1'],

接下对应的字符串在计算机里找对应的Unicode码。

3.Unicode编码,数字的排序方式是 先整理1开头的,然后整理2开头的,依次,所以第二组数组就会出现问题。

那么有没有解决方案呢,当然有了,

1.定义一个比较器

function(x,y) {return x-y}  // 小于0,x移到y前面,大于0,移到y后面。等于0不变

let arr = [5,22,8,36,1]

arr.sort(function(x,y) {return x-y})// [1, 5, 8, 22, 36]

你学会了吗,每天进步一小点,加油!!!

<think> 我们被要求解释C++中sort函数的使用方法。根据引用[1]、[2]、[3],我们可以总结如下: 1. sort函数位于头文件<algorithm>中,因此使用前需要包含该头文件。 2. sort函数可以排序数组、向量等容器。 3. sort函数有两种常用形式: a. 默认形式:sort(起始地址, 结束地址的下一个地址) -> 按升序排序 b. 自定义比较函数形式:sort(起始地址, 结束地址的下一个地址, 比较函数) -> 按自定义规则排序 4. 比较函数:是一个返回bool类型的函数,定义排序规则。当返回true时,表示第一个参数应该排在第二个参数之前。 例如,如果定义比较函数cmp为`bool cmp(int a, int b){ return a>b; }`,那么就会实现降序排序。 5. 对于结构体等自定义类型,通常需要自定义比较函数。 6. 排序范围是左闭右开区间:[起始地址, 结束地址的下一个地址) 接下来,我们通过示例详细说明。 ### 1. 默认排序(升序) ```cpp #include <iostream> #include <algorithm> using namespace std; int main() { int arr[] = {5, 2, 8, 1, 4}; int n = sizeof(arr) / sizeof(arr[0]); // 排序,使用默认的升序 sort(arr, arr + n); // 排序区间为[arr, arr+n) for (int i = 0; i < n; i++) cout << arr[i] << " "; // 输出:1 2 4 5 8 return 0; } ``` ### 2. 自定义比较函数(降序) ```cpp #include <iostream> #include <algorithm> using namespace std; // 自定义比较函数,实现降序 bool cmp(int a, int b) { return a > b; // 当a大于b时,a排在b前面 } int main() { int arr[] = {5, 2, 8, 1, 4}; int n = sizeof(arr) / sizeof(arr[0]); sort(arr, arr + n, cmp); // 使用自定义的cmp函数排序 for (int i = 0; i < n; i++) cout << arr[i] << " "; // 输出:8 5 4 2 1 return 0; } ``` ### 3. 使用内置函数对象(降序) C++标准库提供了`greater<type>()`函数对象,用于实现降序排序(需要包含`<functional>`头文件): ```cpp #include <iostream> #include <algorithm> #include <functional> using namespace std; int main() { int arr[] = {5, 2, 8, 1, 4}; int n = sizeof(arr) / sizeof(arr[0]); sort(arr, arr + n, greater<int>()); // 使用greater进行降序排序 for (int i = 0; i < n; i++) cout << arr[i] << " "; // 输出:8 5 4 2 1 return 0; } ``` ### 4. 对结构体排序 当需要对结构体数组进行排序时,通常需要自定义比较函数。例如,我们有一个结构体Student,我们想按照成绩(score)从高到低排序,如果成绩相同则按照学号(id)从小到大排序。 ```cpp #include <iostream> #include <algorithm> #include <string> using namespace std; struct Student { string id; int score; }; // 自定义比较函数 bool cmp(const Student &a, const Student &b) { if (a.score != b.score) return a.score > b.score; // 成绩高的在前 else return a.id < b.id; // 成绩相同时,学号小的在前 } int main() { Student stu[3] = {{"001", 90}, {"002", 85}, {"003", 90}}; sort(stu, stu + 3, cmp); for (int i = 0; i < 3; i++) cout << stu[i].id << " " << stu[i].score << endl; // 输出: // 001 90 // 003 90 // 002 85 return 0; } ``` ### 5. 对vector排序 sort函数同样适用于vector: ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { vector<int> v = {5, 2, 8, 1, 4}; sort(v.begin(), v.end()); // 升序排序 for (int num : v) cout << num << " "; // 输出:1 2 4 5 8 return 0; } ``` ### 注意事项 1. sort函数的时间复杂度是$O(n \log n)$。 2. 自定义比较函数必须满足严格弱序(Strict Weak Ordering),即: - 非自反性:`comp(a, a)`必须为false。 - 非对称性:如果`comp(a, b)`为true,则`comp(b, a)`必须为false。 - 可传递性:如果`comp(a, b)`为true且`comp(b, c)`为true,则`comp(a, c)`必须为true。 3. 比较函数中的参数类型应该与待排序元素的类型一致。 ### 相关问题 1. 如何在C++中实现自定义数据类型的多关键字排序? 2. C++的sort函数在排序时如何避免拷贝大对象? 3. C++中stable_sortsort的区别是什么? 4. 如何利用lambda表达式简化sort函数的比较函数? 以上内容参考了引用[1][2][3]。 </think>### C++ `sort`函数使用方法详解 #### 1. **基本用法(默认升序)** ```cpp #include <iostream> #include <algorithm> using namespace std; int main() { int arr[] = {45, 12, 34, 77, 90}; int n = sizeof(arr)/sizeof(arr[0]); // 计算数组长度 sort(arr, arr + n); // 默认升序排序 for (int i = 0; i < n; i++) cout << arr[i] << " "; // 输出:12 34 45 77 90 return 0; } ``` - **参数说明**: - `arr`:数组起始地址 - `arr + n`:数组结束地址的下一个位置(左闭右开区间) - **时间复杂度**:$O(n\log n)$[^1][^3] #### 2. **自定义排序规则** ```cpp #include <iostream> #include <algorithm> using namespace std; // 自定义比较函数:降序排列 bool cmp(int a, int b) { return a > b; // a>b时返回true,a排在b前 } int main() { int arr[] = {45, 12, 34, 77, 90}; sort(arr, arr + 5, cmp); // 使用自定义比较函数 for (int i = 0; i < 5; i++) cout << arr[i] << " "; // 输出:90 77 45 34 12 return 0; } ``` - **比较函数要求**: - 返回 `bool` 类型 - 当返回 `true` 时,第一个参数排在第二个参数之前 - 需满足严格弱序(如 $a > b$ 或 $a < b$)[^1][^3] #### 3. **结构体排序** ```cpp #include <iostream> #include <algorithm> using namespace std; struct Student { string name; int score; }; // 按分数降序,同分按名字升序 bool cmp(const Student &a, const Student &b) { if (a.score != b.score) return a.score > b.score; // 分数降序 return a.name < b.name; // 名字升序 } int main() { Student stu[] = {{"Tom", 90}, {"Alice", 85}, {"Bob", 90}}; sort(stu, stu + 3, cmp); for (int i = 0; i < 3; i++) cout << stu[i].name << ": " << stu[i].score << endl; // 输出:Tom:90 Bob:90 Alice:85 return 0; } ``` #### 4. **Lambda表达式(C++11+)** ```cpp vector<int> v = {5, 3, 7, 1}; sort(v.begin(), v.end(), [](int a, int b) { return abs(a-4) < abs(b-4); // 按与4的距离升序 }); // 结果:v = {3,5,1,7} ``` #### 5. **内置函数对象** ```cpp #include <functional> // 使用greater实现降序 sort(arr, arr + n, greater<int>()); // 使用less实现升序(默认) sort(arr, arr + n, less<int>()); ``` ### 关键特性总结 1. **适用范围**: - 数组:`sort(arr, arr + n)` - 向量:`sort(v.begin(), v.end())` - 结构体数组:需自定义比较函数[^3] 2. **排序区间**: - 左闭右开区间 $[start, end)$ - 例:`sort(a+1, a+5)` 排序 $a[1]$ 到 $a[4]$ 3. **注意事项**: - 比较函数必须满足严格弱序 - 对自定义类型排序时需正确定义比较规则 - 排序会改变原始容器内容 ### 相关问题 1. 如何实现多关键字结构体排序(如先按年龄升序,再按分数降序)? 2. `stable_sort` `sort` 有什么区别? 3. 如何对字符串数组进行按长度排序? 4. C++的 `sort` 函数底层使用什么排序算法? > 示例代码参考:引用[1][2][3
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值