`
scott________
  • 浏览: 20763 次
  • 性别: Icon_minigender_1
  • 来自: 哈尔滨
最近访客 更多访客>>
社区版块
存档分类
最新评论

C/C++ 排序 总结 (够用就行,没有刻意追求标准)

阅读更多


1. qsort() (include <stdlib.h>)
      qsort() 采用的是快速排序
      首先要说的是c 语言中的qsort(),不建议使用qsort(),因为
      STL(标准模板库)中的sort() 和 qsort() 的核心都是快速排
      序,通常用sort() 就行了。
     
      函数原型:
          void qsort ( void * base,
                       size_t num,
                       size_t size,
                       int ( * comparator ) ( const void *, const void * ) );//第四个参数可以缺省
   
      base : 待排序数组的首地址
      num  :待排序元素的个数
      size :每个元素的大小(byte), 用sizeof(a[0])即可,a为待排序数组
      comparator: 比较函数指针
      一个简单的调用:(a 为数组名,给十个元素排序)
        qsort(a, 10, seizeof(a[0]));  //第四个参数默认,适用于基本类型的升序
        qsort(a, 10, seizeof(a[0]), compare);
     
     
      比较函数可以如下:
      int compare (const void * a, const void * b)
      {
        return ( *(int*)a - *(int*)b );
      }
     
       个人的理解:比较函数返回第一个元素减去第二个元素,为升序
       排列。反之,降序。

/* qsort example */
#include <stdio.h>
#include <stdlib.h>

int values[] = { 40, 10, 100, 90, 20, 25 };

int compare (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );   //升序排列;调换减数、被减数,则为降序
}

int main ()
{
  int n;
  qsort (values, 6, sizeof(int), compare);
  for (n=0; n<6; n++)
     printf ("%d ",values[n]);
  return 0;
}






2. sort()(#include <algorithm>)
      sort() 目前采用的是加强版的快速排序, 是结合内插排序的快速排序
      目的在于克服快速排序在最初情况(元素基本有序)的效率底下。
     
      函数原型:
           template <class RandomAccessIterator, class Compare>
            void sort ( RandomAccessIterator first,
                        RandomAccessIterator last,
                        Compare comp );    //第三个参数可以缺省
       看起来有点复杂,刚开始我们可以去弱化这个函数原型,把参数都
       当成指针理解:
       first:待排序序列首地址指针
       last :该指针指向最后一个元素的后边
       comp :比较函数指针
       一个简单的调用:(a 为数组名,给十个元素排序)
           sort(a, a + 10);     //比较函数使用默认的,适用于基本类型升序
           sort(a, a + 10, compare)  //自己提供比较函数
      
      比较函数可以如下:
      bool compare (int a, int b)
      {
        return a < b;    //升序;返回a > b,则为降序
      }
     
       个人的理解:比较函数返回第一个元素小于第二个元素,为升序
       排列。反之,降序。注意这个返回值为bool型。



3. stable_sort() (include <algorithm>)
      stable_sort() 采用的是归并排序
      stable_sort() 和 sort() 的参数说明、用法完全相同,只不过
      stable_sort() 为稳定排序,即相等元素的相对顺序在排序后不
      变。有点乱吧,看个例子就会明白的

// stable_sort example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

bool compare_as_ints (double i,double j)
{
  return (int(i)<int(j));
}

int main () {
  double mydoubles1[] = {3.14, 1.41, 2.72, 4.67, 1.73, 1.32, 1.62, 2.58};

  cout << "using default comparison:";
  stable_sort (mydoubles1, mydoubles1 + 8);
  for (int i = 0; i < 8; i++)
    cout<<" "<<mydoubles1[i];

  double mydoubles2[] = {3.14, 1.41, 2.72, 4.67, 1.73, 1.32, 1.62, 2.58};
  cout << "\nusing 'compare_as_ints' :";
  stable_sort (mydoubles2, mydoubles2 + 8, compare_as_ints);
  for (int i = 0; i < 8; i++)
    cout<<" "<<mydoubles2[i];

  cout << endl;

  return 0;
}

Output :




4.partial_sort() (include <algorithm>)
     partial_sort() 采用的是堆排序
    
     函数原型:
         template <class RandomAccessIterator, class Compare>
         void partial_sort ( RandomAccessIterator first,
                             RandomAccessIterator middle,
                             RandomAccessIterator last,
                             Compare comp );  //第四个参数可以缺省
     
     
    功能:排序后[first,middle) 中的元素都小于[middle, last) 中的元素
    但这两个区间中的元素都无序
   
    一个简单的调用:(a 为数组名,假设有12个元素)
           partial_sort (a, a + 5, a + 12);     //比较函数使用默认的,适用于基本类型升序
                                       //前五个元素均小于后边的每个元素,即找出最小的5个元素
           partial_sort (a, a + 5, a + 12, compare)  //自己提供比较函数

    如果希望用partial_sort来实现全排序,只要让middle=last就可以了。


5.nth_element() (include <algorithm>)
     nth_element() 和 partial_sort() 的参数说明、用法完全相同,把
     partial_sort() 中的第二个参数改名为:nth
     执行结果: nth 位置的元素就为待排序序列中的第n 个元素
    
     一个简单的调用:(a 为数组名,假设有12个元素)
           nth_element(a, a + 5, a + 12);     //比较函数使用默认的,适用于基本类型升序
                                              //a[5] 即为数组中第六小元素,注意是第六小
           nth_element(a, a + 5, a + 12, compare)  //自己提供比较函数



    总结  选择合适的排序函数

--------------------------------------------------------------------------------

为什么要选择合适的排序函数?可能你并不关心效率(这里的效率指的是程序运行时间), 或者说你的数据量很小, 因此你觉得随便用哪个函数都无关紧要。
其实不然,即使你不关心效率,如果你选择合适的排序函数,你会让你的代码更容易让人明白,你会让你的代码更有扩充性,逐渐养成一个良好的习惯,很重要吧  。

如果你以前有用过C语言中的qsort, 想知道qsort和他们的比较,那我告诉你,qsort和sort是一样的,因为他们采用的都是快速排序。从效率上看,以下几种sort算法的是一个排序,效率由高到低(耗时由小变大):

partion
stable_partition
nth_element
partial_sort
sort
stable_sort
记得,以前翻译过Effective STL的文章,其中对如何选择排序函数总结的很好:
若需对vector, string, deque, 或 array容器进行全排序,你可选择sort或stable_sort;
若只需对vector, string, deque, 或 array容器中取得top n的元素,部分排序partial_sort是首选.
若对于vector, string, deque, 或array容器,你需要找到第n个位置的元素或者你需要得到top n且不关系top n中的内部顺序,nth_element是最理想的;
若你需要从标准序列容器或者array中把满足某个条件或者不满足某个条件的元素分开,你最好使用partition或stable_partition;
若使用的list容器,你可以直接使用partition和stable_partition算法,你可以使用list::sort代替sort和stable_sort排序。若你需要得到partial_sort或nth_element的排序效果,你必须间接使用。正如上面介绍的有几种方式可以选择。
总之记住一句话: 如果你想节约时间,不要走弯路, 也不要走多余的路!


参考文献:
1.李忠军博 http://blogold.chinaunix.net/u/21813/showart_211598.html
2.c++在线文档http://www.cplusplus.com/
  • 大小: 1.1 KB
  • 大小: 3.1 KB
分享到:
评论

相关推荐

    C/C++排序算法

    C/C++排序算法总结 快速 插入 冒泡 希尔

    C语言/C++集成开发环境 Dev-C++

    C语言/C++集成开发环境 Dev-C++。一款优秀的C/C++集成开发软件。

    Dev-cpp5.4.0及API帮助文档 2018年蓝桥杯C语言/c++

    Dev-cpp5.4.0及API帮助文档 2018年蓝桥杯C语言/c++ 需要的同学可以下载使用

    C语言/C++ 烟花表白代码

    C语言/C++ 烟花表白代码 C语言/C++ 烟花表白代码 C语言/C++ 烟花表白代码 C语言/C++ 烟花表白代码

    C/C++ 标准库函数 (中文版)

    C/C++ 标准库函数手册。 包含大部分常用的标准库函数、标准模版库和关键字等描述。

    Pro*C/C++ 编程

    Pro*C/C++ 编程 1 一、Pro*C/C++ 简介 1 1.1、Pro*C/C++ 是什么 1 1.2、Pro*C/C++ 处理流程 2 二、Pro*C/C++ GCC 环境配置 3 2.1、Pro*C/C++ 预编译环境 3 2.2、GCC 编译器 5 三、开始编写第一个Pro*C++代码 5 3.1、...

    C语言/C++基础之爱心源码

    C语言/C++基础之爱心源码,适合初学C语言/C++的小伙伴学习研究,博客中有对应的讲解和演示,避免走弯路,费时费力。也真心希望能够帮助正在苦学C语言/C++ 程序设计的小伙伴们,你们的成长是我最大的幸福

    c语言/c++/qt图形界面

    c语言/c++/qt图形界面

    c/c++中文帮助文档(API)

    c/c++中文帮助文档(API),包含c和c++所有的库函数

    二维码(QRcode)生成算法 C语言/C++源码

    #二维码(QRcode)生成算法 C语言/C++ 源码 1. 根据输入字符串识别编码模式; 2. 根据输入字符串长度选择合适的QRcode版本; 3. 将编码转换为二进制位流表示为数据码字; 4. 使用多项式生成纠错码; 5. 将数据码和...

    C语言/C++基础之爱心程序源码

    C语言/C++基础之爱心程序源码,适合初学C语言/C++的小伙伴学习研究,博客中有对应的讲解和演示,避免走弯路,费时费力。也真心希望能够帮助正在苦学C语言/C++ 程序设计的小伙伴们,你们的成长是我最大的幸福

    C语言/C++基础之冰墩墩源码

    C语言/C++基础之冰墩墩源码,适合初学C语言/C++的小伙伴学习研究,博客中有对应的讲解和演示,避免走弯路,费时费力。也真心希望能够帮助正在苦学C语言/C++ 程序设计的小伙伴们,你们的成长是我最大的幸福

    基于C语言/C++基础的跨年烟花代码

    C语言/C++基础之跨年烟花代码,适合初学C语言/C++的小伙伴学习研究,博客中有对应的讲解和演示,避免走弯路,费时费力。也真心希望能够帮助正在苦学C语言/C++ 程序设计的小伙伴们,你们的成长是我最大的幸福

    C/C++程序设计学习与实验系统 V2008.13.part1

    软件集成了高校 C/C++语言教学中使用最多的三种编译器 Visual C++ 6.0 、Turbo C++3.0和Turbo C 2.0 ,给高校 C/C++的实验教学提供了简单易用的软件实验环境(软件没有使用日期限制,可以无限期使用)。与软件配套的...

    c / c++ / cpp / stl 中文帮助文档手册chm格式下载

    c / c++ / cpp / stl 中文帮助文档手册chm格式下载 C/C++ 语言参考 基本C/C++ 预处理命令 操作符优先级 转义字符 ASCII码表 基本数据类型 关键字 标准 C 库: Standard C I/O Standard C String...

    C/C++中文文档(支持C++20和C18)和蓝桥杯C/C++组用的文档

    这个文档压缩包包含普通C/C++中文文档和蓝桥杯比赛时用的文档,C/C++中文文档是最新版,支持到C++20和C18,且包含以前版本的内容。蓝桥杯蓝桥杯C/C++组用的文档比正常文档更简略,但包含了ASCII码表。

    C语言/C++基础之跨年烟花代码

    C语言/C++基础之跨年烟花代码,适合初学C语言/C++的小伙伴学习研究,博客中有对应的讲解和演示,避免走弯路,费时费力。也真心希望能够帮助正在苦学C语言/C++ 程序设计的小伙伴们,你们的成长是我最大的幸福

    2021年最新 C/C++中文参考手册

    2021年最新 C/C++中文参考手册

Global site tag (gtag.js) - Google Analytics