zoukankan      html  css  js  c++  java
  • c++中sort()及qsort()的使用方法总结

     当并算法具体解释请见点我

    想起来自己天天排序排序,冒泡啊,二分查找啊,结果在STL中就自带了排序函数sort,qsort,总算把自己解脱了~
    所以自己总结了一下,首先看sort函数见下表:

      函数名 功能描写叙述 
    sort 对给定区间全部元素进行排序 
    stable_sort 对给定区间全部元素进行稳定排序 
    partial_sort 对给定区间全部元素部分排序 
    partial_sort_copy 对给定区间复制并排序 
    nth_element 找出给定区间的某个位置相应的元素 
    is_sorted 推断一个区间是否已经排好序 
    partition 使得符合某个条件的元素放在前面 
    stable_partition 相对稳定的使得符合某个条件的元素放在前面 

    要使用此函数仅仅需用#include <algorithm> sort就可以使用,语法描写叙述为:
    sort(begin,end),表示一个范围,比如:
    int _tmain(int argc, _TCHAR* argv[])
    {
     int a[20]={2,4,1,23,5,76,0,43,24,65},i;
     for(i=0;i<20;i++)
      cout<<a[i]<<endl;
     sort(a,a+20);
     for(i=0;i<20;i++)
     cout<<a[i]<<endl;
     return 0;
    }
    输出结果将是把数组a按升序排序,讲到这里可能就有人会问怎么样用它降序排列呢?这就是下一个讨论的内容.
    一种是自己编写一个比較函数来实现,接着调用三个參数的sort:sort(begin,end,compare)就成了。对于list容器,这种方法也适用,把compare作为sort的參数就能够了,即:sort(compare).

    1)自己编写compare函数:
    bool compare(int a,int b)
    {
      return a<b; //升序排列,假设改为return a>b,则为降序
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
      int a[20]={2,4,1,23,5,76,0,43,24,65},i;
      for(i=0;i<20;i++)
      cout<<a[i]<<endl;
      sort(a,a+20,compare);
      for(i=0;i<20;i++)
      cout<<a[i]<<endl;
      return 0;
    }

    2)更进一步,让这样的操作更加能适应变化。也就是说,能给比較函数一个參数,用来指示是按升序还是按降序排,这回轮到函数对象出场了。
    为了描写叙述方便,我先定义一个枚举类型EnumComp用来表示升序和降序。非常easy:
    enum Enumcomp{ASC,DESC};
    然后開始用一个类来描写叙述这个函数对象。它会依据它的參数来决定是採用“<”还是“>”。

    class compare
    {
      private:
      Enumcomp comp;
      public:
      compare(Enumcomp c):comp(c) {};
      bool operator () (int num1,int num2)
      {
      switch(comp)
      {
      case ASC:
      return num1<num2;
      case DESC:
      return num1>num2;
      }
      }
    };

    接下来使用 sort(begin,end,compare(ASC)实现升序,sort(begin,end,compare(DESC)实现降序。
    主函数为:
    int main()
    {
      int a[20]={2,4,1,23,5,76,0,43,24,65},i;
      for(i=0;i<20;i++)
      cout<<a[i]<<endl;
      sort(a,a+20,compare(DESC));
      for(i=0;i<20;i++)
      cout<<a[i]<<endl;
      return 0;
    }
    3)事实上对于这么简单的任务(类型支持“<”、“>”等比較运算符),全然不是必需自己写一个类出来。标准库里已经有现成的了,就在functional里,include进来即可了。functional提供了一堆基于模板的比較函数对象。它们是(看名字就知道意思了):equal_to<Type>、not_equal_to<Type>、greater<Type>、greater_equal<Type>、less<Type>、less_equal<Type>。对于这个问题来说,greater和less就足够了,直接拿过来用:

    升序:sort(begin,end,less<data-type>());
    降序:sort(begin,end,greater<data-type>()).
    int _tmain(int argc, _TCHAR* argv[])
    {
      int a[20]={2,4,1,23,5,76,0,43,24,65},i;
      for(i=0;i<20;i++)
      cout<<a[i]<<endl;
      sort(a,a+20,greater<int>());
      for(i=0;i<20;i++)
      cout<<a[i]<<endl;
      return 0;
    }
    4)既然有迭代器,假设是string 就能够使用反向迭代器来完毕逆序排列,程序例如以下:
    int main()
    {
      string str("cvicses");
      string s(str.rbegin(),str.rend());
      cout << s <<endl;
      return 0;
    }
    qsort():
    原型:
    _CRTIMP void __cdecl qsort (void*, size_t, size_t,int (*)(const void*, const void*));
    解释: qsort ( 数组名 ,元素个数,元素占用的空间(sizeof),比較函数)
    比較函数是一个自己写的函数 遵循 int com(const void *a,const void *b) 的格式。
    当a b关系为 > < = 时,分别返回正值 负值 零 (或者相反)。
    使用a b 时要强制转换类型,从void * 转换回应有的类型后,进行操作。
    数组下标从零開始,个数为N, 下标0-(n-1)。
    实例:
    int compare(const void *a,const void *b)
    {
      return *(int*)b-*(int*)a;  
    }
    int main()
    {
      int a[20]={2,4,1,23,5,76,0,43,24,65},i;
      for(i=0;i<20;i++)
      cout<<a[i]<<endl;
      qsort((void *)a,20,sizeof(int),compare);
      for(i=0;i<20;i++)
      cout<<a[i]<<endl;
      return 0;
    }
    相关:
    1)why你必须给予元素个数?
    由于阵列不知道它自己有多少个元素
    2)why你必须给予大小?
    由于 qsort 不知道它要排序的单位.
    3)why你必须写那个丑陋的、用来比較俩数值的函式?
    由于 qsort 须要一个指标指向某个函式,由于它不知道它所要排序的元素型别.
    4)why qsort 所使用的比較函式接受的是 const void* 引数而不是 char* 引数?
    由于 qsort 能够对非字串的数值排序.
    当然对于排序函数还有其它的使用方法,今天就仅仅说这些,我也正在学习中,上述仅仅是发表了一点自己的拙见,最后声明上诉实例是基于VC++2008。

    二维字符数组排序

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    struct Data
    {
    	char data[100];	
    }str[100];
    
    bool cmp(const Data &elem1, const Data &elem2)
    {
    	if (strcmp(elem1.data, elem2.data) < 0)
    		return true;
    	return false;
    }
    
    
    int main()
    {
    	int n, i;
    	while (cin>>n)
    	{
    		for (i=0; i<n; ++i)
    		{
    			cin>>str[i].data;
    		}
    		
    		sort(str, str+n, cmp);
    		
    		for (i=0; i<n; ++i)
    			cout<<str[i].data<<endl;
    	}
    	return 0;
    }


     

    代码二:

    bool cmp(const char *elem1, const char *elem2)
    {
     if (strcmp(elem1, elem2) < 0)
      return true;
     return false;
    }
    
    int main()
    {
     char str[100][100];
     char *pStr[100] = {NULL};
     int n, i;
     while (cin>>n)
     {
      for (i=0; i<n; ++i)
      {
       cin>>str[i]; 
       pStr[i] = str[i];
       }
      sort(pStr, pStr+n, cmp);
      for (i=0; i<n; ++i)
       cout<<pStr[i]<<endl;
     }
     return 0;
    }
    
    



    qsort()

    #include <iostream>
    #include <algorithm>
    using namespace std;
    int cmp(const void *a,const void *b){
      return strcmp((char*)a,(char *)b);	
    }
    
    struct tel{
    	char phone[10];
    }tel[10];
    int main(){
       int cases;
       int i;
       cin >> cases;
       char tel[20][10];
       for(i = 0; i < cases; ++i)
       cin >> tel[i];
       qsort(tel,cases,sizeof(char)*10,cmp);
       for(int j = 0; j < i; ++j)
       cout << tel[j] << endl;
    }



     

  • 相关阅读:
    LeetCode 461. Hamming Distance
    LeetCode 442. Find All Duplicates in an Array
    LeetCode 448. Find All Numbers Disappeared in an Array
    LeetCode Find the Difference
    LeetCode 415. Add Strings
    LeetCode 445. Add Two Numbers II
    LeetCode 438. Find All Anagrams in a String
    LeetCode 463. Island Perimeter
    LeetCode 362. Design Hit Counter
    LeetCode 359. Logger Rate Limiter
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4231680.html
Copyright © 2011-2022 走看看