以下内容来自《C/C++程序设计实用案例教程》

1、排序

1.1使用qsort函数

  C/C++库函数提供了快速排序函数qsort(q时quick的简写),需要引入头文件<stdlib.h>(注:C++中尽量使用<cstdlib>)

  C/C++中库函数qsort函数声明如下:

void qsort(void* base, size_t num, size_t size, int(*compar)(const void*, const void*));

  第一个参数base:待排序的元素数组起始地址

  第二个参数num:待排序的数组中元素个数

  第三个参数size:每个元素的大小(字节数)

  最后一个参数:排序的比较函数

例子:整形数组的qsort

#include <stdlib.h>

int compare(const void* a, const void* b)	//这里要注意的是参数的类型必须为const void*
{
if (*(int*)a < *(int*)b)
return -1;
else if (*(int*)a == *(int*)b)
return 0;
else
return 1;
}
int main()
{
int a[] = { 12, 46, 154, 4, 86, 5, 78, 5, 8, 16, 879, 4, 78, 5, 45, 12, 45, 45, 71, 1, 4, 78, 979, 46, 7, 9 };
size_t num = sizeof(a) / sizeof(int);
size_t size = sizeof(int); qsort(a, num, size, compare);
return 0;
}

  

结果

例子:字符串数组的qsort

#include <stdlib.h>	//qsort
#include <string.h> //strcmp //字符串数组的qsort
int compare(const void* a, const void* b)
{
return strcmp(*(char**)a, *(char**)b);
} int main()
{
char* str[] = { "fad", "fdfetr", "qwtwt", "nbdf", "twtyw", "wywr", "rwew", "sfb" }; qsort(str, sizeof(str) / sizeof(char*), sizeof(char*), compare);
return 0;
}

  

结果

1.2使用std::sort排序

  在C++中,更推荐使用STL库函数中的std::sort。因为C++STL中并没有明确指明std::sort使用的排序算法,这也意味不同的平台在std::sort函数实现时可能采用不同的排序算法。

  std::sort两个重载函数声明如下,需引入头文件<algorithm>

template<class RandomAccessIterator>
void sort(RandomAccessIterator first, RandomAccessIterator last); template<class RandomAccessIterator,class Compare>
void sort(RandomAccessIterator first,RandomAccessIterator last,Compare comp)

  第一个重载函数只需传入一个迭代器区间,也就是开始和终止位置的两个随机访问迭代器。它只能进行升序排列。

  第二个重载函数还需要传入比较函数。

  这里再次涉及迭代器区间,在STL的所有库函数中,如果涉及迭代器区间,那么这个区间一定是半闭半开区间,也就是[first,last)。

  在qsort函数中,一定要传入一个比较函数,但是在std::sort的第一个重载函数中,并没有比较函数。这是因为qsort处理的数据都是无符号类型的指针,在编译时候它无法知道数据元素的确切类型。

  而std::sort采用的是C++模板方法,当数据传入到比较函数时,它的类型在编译时就确定了。

  第二个重载函数中如何定义比较函数?

  comp实际上是一个二元函数,它的参数应该是待排序区间中的两个元素,而不是元素的指针;

  comp的返回值是bool类型,当返回值为true时,表示a排在b的前面,因此,std:;sort的比较函数相比于qsort的比较函数显得比较简捷,因为qsort比较函数的返回值包括0、负整数、正整数,分别表示等于、小于和大于;

  同样,std::sort的比较函数可以是一个函数指针,也可以是一个函数对象。

示例代码如下:

#include <iostream>
#include <algorithm> //双精度升序比较函数
bool DoubleAscend(double i, double j)
{
return i < j;
}
//双精度降序比较函数
bool DoubleDescend(double i, double j)
{
return j < i;
}
//函数对象做比较函数
struct CompareClass
{
bool operator()(double i, double j){ return j < i; }
} compareDescendObject; int main()
{
double data[] = { 32.5, 71.3, 12.1, 45.4, 26.8, 80.9, 53.2, 32.5 };
int n = sizeof(data) / sizeof(double);
//使用double默认升序
std::sort(data, data + n);
for (int i = 0; i < n; i++)
std::cout << data[i] << " ";
std::cout << std::endl; //对前四个元素按降序排序
std::sort(data, data + 4, DoubleDescend);
for (int i = 0; i < n; i++)
std::cout << data[i] << " ";
std::cout << std::endl; //对后四个元素按降序排序
std::sort(data + n - 4, data + n, DoubleDescend);
for (int i = 0; i < n; i++)
std::cout << data[i] << " ";
std::cout << std::endl; //使用自定义比较类的一个实例化对象对所有元素按降序排序
std::sort(data, data + n, compareDescendObject);
for (int i = 0; i < n; i++)
std::cout << data[i] << " ";
std::cout << std::endl;
}

  

结果:

补充:

  对于基本数据,STL已经准备了降序排序的函数模板std::greater。对于非基本数据类型,如结构体或类,只要其重载operator<函数,则可以直接使用std::greater进行降序排序。

  使用std::greater时需要引入头文件<functional>。

  与降序相对应的是升序std::less(可以用,但没必要,因为默认就是升序的)。

例子

#include <iostream>
#include <algorithm>
#include <functional> int main()
{
double data[] = { 32.5, 71.3, 12.1, 45.4, 26.8, 80.9, 53.2, 32.5 };
int n = sizeof(data) / sizeof(double); //按降序排序
std::sort(data, data + n, std::greater<double>());
for (int i = 0; i < n; i++)
std::cout << data[i] << " ";
std::cout << std::endl;
}

  

结果

2、查找

2.1使用bsearch函数

  C语言库函数提供了一个二分查找函数bsearch,需要引入头文件<stdlib.h>

  函数声明如下:

void* bsearch(const void* key, const void* base, size_t num, size_t size, int(*compar)(const void*, const void*));

  bsearch的函数参数列表和qsort非常类似,只是它多了第一个参数:一个待查找值的指针,如果在数组中成功查找该值,则返回该值所在空间的地址;如果数组中有多个相同的待查找值,则可能返回其中任意一个值的地址,如果查找失败,返回null指针。

示例代码:

#include <stdlib.h>	//qsort,bsearch

int compareInt(const void* a, const void* b)
{
return *(int*)a - *(int*)b;
} int main()
{
int values[] = { 50, 20, 60, 40, 10, 30 };
int key;
int *pltem; key = 30;
qsort(values, sizeof(values) / sizeof(int), sizeof(int), compareInt); //使用二分法查找需要先进行排序
pltem = (int*)bsearch(&key, values, sizeof(values) / sizeof(int), sizeof(int), compareInt);
return 0; }

  

结果

2.2std::find查找

  std::find是C++ STL库函数中一个通用的查找函数,这个函数并不要求输入的数据集合是已排序的。

  std::find需引入头文件<algorithm>

  其函数声明如下:

template<class InputIterator,class T>
InputIterator find(InputIterator first, InputIterator last, const T& val);

  它会返回[first,last)区间内第一个和val相等的元素的迭代器。如果没有找到该元素,函数返回的是last迭代器。

示例代码:

#include <algorithm>

int main()
{
int data[] = { 35, 25, 10, 15, 45 };
int *p, n;
n = sizeof(data) / sizeof(int);
p = std::find(data, data + n, 15);
return 0;
}

结果

C/C++中的排序和查找的更多相关文章

  1. vector向量容器元素排序与查找

    1.利用标准库函数sort()对vector进行排序 参考源码: #include <algorithm> #include <vector> vector<int> ...

  2. Java中的排序算法(2)

    Java中的排序算法(2) * 快速排序 * 快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists). * 步骤为: * 1. 从数 ...

  3. STL笔记(6)标准库:标准库中的排序算法

    STL笔记(6)标准库:标准库中的排序算法 标准库:标准库中的排序算法The Standard Librarian: Sorting in the Standard Library Matthew A ...

  4. 对于Oracle中分页排序查询语句执行效率的比较分析

    转自:http://bbs.csdn.net/topics/370033478 对于Oracle中分页排序查询语句执行效率的比较分析 作者:lzgame 在工作中我们经常遇到需要在Oracle中进行分 ...

  5. mongodb中的排序和索引快速学习

    在mongodb中,排序和索引其实都是十分容易的,先来小结下排序: 1 先插入些数据    db.SortTest.insert( { name : "Denis", age : ...

  6. .Net中集合排序的一种高级玩法

    背景: 学生有名称.学号, 班级有班级名称.班级序号 学校有学校名称.学校编号(序号) 需求 现在需要对学生进行排序 第一排序逻辑 按学校编号(序号)排列 再按班级序号排列 再按学生学号排列 当然,在 ...

  7. Golang的排序和查找

    Golang的排序和查找 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.排序的基本介绍 排序是将一组数据,依指定的顺序进行排列的过程.排序的分类如下 1>.内部排序 指将 ...

  8. JavaScript中简单排序总结

    JavaScript中简单排序总结 冒泡排序 经典排序算法, 双重for循环 在第二个for循环的时候, j < arr.len -1 -i , 这一步的优化很重要 function bullS ...

  9. NumPy 排序、查找、计数

    章节 Numpy 介绍 Numpy 安装 NumPy ndarray NumPy 数据类型 NumPy 数组创建 NumPy 基于已有数据创建数组 NumPy 基于数值区间创建数组 NumPy 数组切 ...

随机推荐

  1. Download EditPlus Text Editor

    突然发现EditPlus还是很强大的,很好用,破解也很方便,有个牛人做了在线生成验证码,只能说服!! 下边把官网的最新下载地址贴出,当然还有在线生成验证码喽. EditPlus Text Editor ...

  2. 【转】Java多线程面试问题集锦

    如果你即将去一家从事大型系统研发的公司进行Java面试,不可避免的会有多线程相关的问题.下面是一些针对初学者或者新手的问题,如果你已经具备良好的基础,那么你可以跳过本文,直接尝试针对进阶水平的Java ...

  3. i3s 一种开源的三维地理数据规范 简单解读

    i3s,esri主推到ogc的一种三维开源GIS数据标准. 版权声明:原创.博客园/B站/小专栏/知乎/CSDN @秋意正寒 转载请标注原地址并声明转载: https://www.cnblogs.co ...

  4. FJUT-1370 记录一次解题过程

    题目在福工院的1370 首先看题目,好家伙,全英文 那么大致的题意就是.有几个城市同在一条线上(相当于在x轴上),max i是第i个城市到其他所有城市的距离中的最大值,min i也就是所有中最小的. ...

  5. js最简单的编写地点

    1. 在哪里? 在浏览器的控制台. 2. 有什么作用? 方便快捷的测试纯js代码语句. 3. 如何使用? Google浏览器为例:  按 F12键  打开 开发者工具  (或者 浏览器工具栏 => ...

  6. 区间dp - 不连续的回文串

    Long long ago, there lived two rabbits Tom and Jerry in the forest. On a sunny afternoon, they plann ...

  7. Hive 这些基础知识,你忘记了吗?

    Hive 其实是一个客户端,类似于navcat.plsql 这种,不同的是Hive 是读取 HDFS 上的数据,作为离线查询使用,离线就意味着速度很慢,有可能跑一个任务需要几个小时甚至更长时间都有可能 ...

  8. Vue中的nextTick()浅析

    引言 在开发过程中,我们经常遇到这样的问题:我明明已经更新了数据,为什么当我获取某个节点的数据时,却还是更新前的数据? 一,浅析 为什么会这样呢?带着这个疑问先往下看. 先看一个小的例子: <d ...

  9. Docker学习(三)认识Docker和常用命令

    Docker学习(三)认识Docker和常用命令 Docker体系结构 docker服务端,作为服务的提供方,核心进程 docker daemon,所有docker命令都是通过这个进程完成的 REST ...

  10. 洛谷 UVA1395 苗条的生成树 Slim Span

    题目链接 题目描述 求所有生成树中最大边权与最小边权差最小的,输出它们的差值. 题目分析 要求所有生成树中边权极差最小值,起初令人无从下手.但既然要求所有生成树中边权极差最小值,我们自然需要对每一棵生 ...