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;
}

结果

原文地址:https://www.cnblogs.com/XiaoXiaoShuai-/p/10453105.html

时间: 2025-01-18 04:48:25

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

排序,查找,qsort和bsearch的简单总结,scanf字符串截取

有一些时候,一些方便用户做的设计,往往会降低产品本身的安全性. 安全性与易用性,是一道产品设计者需要仔细思考的题. ========================================================================================================== 好了,切入正题.最近在练题,或者说刷题,发现自己不知道的东西还真不少,得好好补补啦~ 首先就是c语言的两个,也是唯一的两个与排序搜索相关的函数,记得之前自己还很仔细的去背

java 数组比较,元素的比较,Comparable,Comparator比较的应用实现,排序,查找示例

java 数组比较,元素的比较,自定义Comparator的实现,排序,查找示例 package org.rui.array.compar; import java.util.Arrays; import java.util.Random; import org.rui.generics.anonymity.Generator; /** * 程序设计的基本目标是"将保持不变的事物与会发生改变的事物相分离" * 而这是,不变的是通用的排序算法,变化的是各种对象相互比较的方式, * 因此,

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

STL笔记(6)标准库:标准库中的排序算法 标准库:标准库中的排序算法The Standard Librarian: Sorting in the Standard Library Matthew Austern http://www.cuj.com/experts/1908/austern.htm?topic=experts 用泛型算法进行排序    C++标准24章有一个小节叫“Sorting and related operations”.它包含了很多对已序区间进行的操作,和三个排序用泛型

所有的排序、查找算法

import javax.mail.Part; /** * 顺序查找.排序 * * @author 曾修建 * @version 创建时间:2014-7-30 下午04:15:10 */ public class SequentialSearch { public static void main(String[] args) { Integer[] a = {1,2,3,4,5,7,6,88}; //二分查找非递归 System.out.println( "二分查找非递归实现 位置 : &qu

排序和查找算法的使用

TBOX提供了各种常用算法,对容器中的元素进行各种操作,这里主要介绍下排序和查找算法. 排序算法目前支持如下几种: 快速排序:tb_quick_sort 堆排序: tb_heap_sort 插入排序:tb_bubble_sort 冒泡排序:tb_insert_sort 并且提供通用的tb_sort接口,对各种排序算法进行自动适配,使得任何情况下,性能都是最优的. 例如: 对具有随机迭代特性的容器,采用库快速排序来优化 对具有随机迭代特性,并且是超大规模的容器,采用堆排序 对只能线性迭代的容器采用

使用qsort()和bsearch()函数对值和字符串进行排序和查找

#include <stdio.h> #include <stdlib.h> #define MAX 20 int intcmp(const void *v1, const void *v2); int main(void){   int arr[MAX], count, key, *ptr;      //提示用户输入一些整数    printf("Enter %d integer values; press Enter each.\n", MAX);   f

华为训练题:中级——字符串排序(查找)

编写一个程序,将输入字符串中的字符按如下规则排序. 规则1:英文字母从A到Z排列,不区分大小写. 如,输入:Type 输出:epTy 规则2:同一个英文字母的大小写同时存在时,按照输入顺序排列. 如,输入:BabA 输出:aABb 规则3:非英文字母的其它字符保持原来的位置. 如,输入:By?e 输出:Be?y 样例: 输入: A Famous Saying: Much Ado About Nothing(2012/8). 输出: A aaAAbc dFgghh: iimM nNn oooos 

数据结构实践——二叉树排序树中查找的路径

本文是[数据结构基础系列(8):查找]中的实践项目参考. [项目 - 二叉树排序树中查找的路径] 设计一个算法,输出在二叉排序中查找时查找某个关键字经过的路径. [参考解答] 专为本项目设计的算法体现在函数int SearchBST(-)和void SearchResult()中. #include <stdio.h> #include <malloc.h> #define MaxSize 100 typedef int KeyType; //定义关键字类型 typedef cha

数组的排序与查找

/**对如下一个数组int[] iarr={34,67,1,56,32,78,12,45,79,4,57,102,123,3};进行排序(采用自己擅长的排序算法),然后查询排序之后的采用二分查找*法查找45在在数组的索引值 ,排序.查找封装成方法,然后在main方法中调用测试.*/ public class FenDou01 { public static void main(String[] args) { int[] iarr={34,67,1,56,32,78,12,45,79,4,57,