zoukankan      html  css  js  c++  java
  • C/C++中的排序和查找

    以下内容来自《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;
    }
    

    结果

  • 相关阅读:
    webService总结(一)——使用CXF公布和调用webService(不使用Spring)
    男人最佳的生育年限,程序猿们,看看吧!!!
    软考之路(5)——计算机组成原理之加密技术和认证技术
    新安装mysql 第三方工具连接不上问题
    JQuery text()、html() 以及 val()
    DOM
    Spring Boot 学习
    JSON
    Nodejs 配置+基础
    配置-
  • 原文地址:https://www.cnblogs.com/XiaoXiaoShuai-/p/10453105.html
Copyright © 2011-2022 走看看