前言:qsort和sort都是系统提供给我们的可以直接排序的两个函数。在面试的时候手写代码需要排序的时候可以直接去调用这两个函数 。我自己在A题目的时候遇到了排序函数的问题,用了sort , AC不过,用了qsort竟然过了。。搞不懂。来看一下两者的区别,并分析下当时出现的错误原因。
// // main.cpp // sortAndqsortExample // // Created by mini on 12/20/13. // Copyright (c) 2013 mini. All rights reserved. // #include <iostream> #include <string.h> using namespace std; int cmp (const void * a, const void * b) { if ( *(int*)a < *(int*)b ) return 1; else return -1; } int main(int argc, const char * argv[]) { int a[ ] = {5, 211111111, -211111111, 7, 8, 2}; qsort(a, 6, sizeof( a[ 0 ] ), cmp); for( int i = 0; i < 6; i++ ) cout << a[ i ] << " "; cout << endl; return 0; }
int cmp (const void * a, const void * b) { return *( int * ) a - *( int * )b; }如果直接写成这个样子的话,当排序的数组值很大的时候,有可能会造成溢出的问题。看下面的代码:
#include <iostream> #include <string.h> using namespace std; int cmp (const void * a, const void * b) { return *( int * ) a - *( int * )b; } int main(int argc, const char * argv[]) { int a[ ] = {5, 2147483646, -2147483646, 7, 8, 2}; qsort(a, 6, sizeof( a[ 0 ] ), cmp); for( int i = 0; i < 6; i++ ) cout << a[ i ] << " "; cout << endl; return 0; }
#include <iostream> #include <string.h> using namespace std; struct Student{ int number; int age; char s; }; int cmp (const void * a, const void * b) { struct Student * p = (Student *) a; struct Student * q = (Student *) b; if( p -> number < q -> number ) return -1; else if ( p ->number > q -> number ) return 1; else return ( p -> age < q -> age ) ? -1 : 1; } int main(int argc, const char * argv[]) { Student A[ 5 ]; A[ 0 ] = { 5,8,'c'}; A[ 1 ] = { 8,8,'c'}; A[ 2 ] = { 6,6,'c'}; A[ 3 ] = { 6,8,'c'}; A[ 4 ] = { 2,8,'c'}; qsort( A, 5, sizeof(Student), cmp ); for( int i = 0; i < 5; i++ ) cout << A[ i ].number << " " << A[ i ].age << " " << A[ i ].s << endl; return 0; }output:
2 8 c 5 8 c 6 6 c 6 8 c 8 8 c
template< class RandomIt > void sort( RandomIt first, RandomIt last ); (1) template< class RandomIt, class Compare > void sort( RandomIt first, RandomIt last, Compare comp );
bool cmp(const Type1 &a, const Type2 &b);参数的形式不一定要定义为const &,但是在cmp函数中不能修改参数的值。 函数返回true 如果第一参数小于第二个参数。
#include <algorithm> #include <iostream> #include <string> #include <array> using namespace std; bool cmp( const int & a, const int & b ){ return a < b; } int main() { array< int, 10 > s ={ 5,2,3,8,1,9,0,7,4,6}; sort( s.begin(), s.end(), less< int >()); //sort( s.begin(), s.end() ); for( int a: s ) cout << a << " "; cout << endl; sort( s.begin(), s.end(), greater< int >()); for( int a: s ) cout << a << " "; cout << endl; sort( s.begin(), s.end(), cmp); for( int a: s ) cout << a << " "; cout << endl; return 0; }
0 1 2 3 4 5 6 7 8 9 9 8 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9
template< class RandomIt > void partial_sort( RandomIt first, RandomIt middle, RandomIt last ); (1) template< class RandomIt, class Compare > void partial_sort( RandomIt first, RandomIt middle, RandomIt last, Compare comp ); (2)这个函数的作用是[first,middle)区间中包含排序后的函数,这个排序函数也是不稳定函数,不能保证相同值的元素在排序后的前后次序不发生变化。 自定义函数和sort 类似。
#include <algorithm> #include <iostream> #include <string> #include <array> using namespace std; bool cmp( const int & a, const int & b ){ return a < b; } int main() { array< int, 10 > s ={ 5,2,3,8,1,9,0,7,4,6}; partial_sort( s.begin(), s.begin() + 4, s.end()); for( int a: s ) cout << a << " " ; cout << endl; return 0; }
#include <algorithm> #include <iostream> #include <string> #include <vector> using namespace std; struct Employee { Employee(int age, std::string name) : age(age), name(name) { } int age; string name; // Does not particpate in comparisons }; bool operator<(const Employee &lhs, const Employee &rhs) { return lhs.age < rhs.age; } int main() { std::vector<Employee> v = { Employee(108, "Haha"), Employee(108, "Zaphod"), Employee(108, "Ford"), Employee(32, "Arthur"), }; stable_sort(v.begin(), v.end()); for (const Employee &e : v) { cout << e.age << ", " << e.name << '\n'; } }
32, Arthur 108, Haha 108, Zaphod 108, Ford可以看出值等于108的三个元素的前后次序是没有变化的,所以它叫稳定排序。
template< class RandomIt > void nth_element( RandomIt first, RandomIt nth, RandomIt last ); (1) template< class RandomIt, class Compare > void nth_element( RandomIt first, RandomIt nth, RandomIt last, Compare comp ); (2)
#include <iostream> #include <vector> #include <algorithm> #include <functional> using namespace std; int main() { std::vector<int> v{5, 6, 4, 3, 2, 7, 9, 1, 0, 8}; std::nth_element(v.begin(), v.begin() + v.size()/2, v.end()); std::cout << "The median is " << v[v.size()/2] << '\n'; for( int a : v ) cout << a << " "; cout << endl; std::nth_element(v.begin(), v.begin()+1, v.end(), std::greater<int>()); std::cout << "The second largest element is " << v[1] << '\n'; for( int a : v ) cout << a << " "; cout << endl; }
The median is 5 0 1 2 3 4 5 6 7 9 8 The second largest element is 8 9 8 7 6 5 4 3 2 1 0可以看出来,5前面都是比它小的,后面的都是比它大的。但是并不一定是排序的。