2.1 检索;2.2 排序;2.3 库

2.1检索

    数组是我们经常使用到的东西,一个例子就是储存静态的表格式数据。在实际应用中,我们往往需要找到数组中的特定数据。对于这种问题,终止整个搜索的一种处理方法是传递一个数组长度参数,而这里采取在数组最后放一个NULL作为结束参数。使用一个数组数据寻找函数作为遍历。

char *flab[] = {
		"actually",
		"just",
		"quite",
		"really",
		NULL
	};
int lookup(char *word, char *array[])
{
	int i;
	for (i = 0; array[i]; i++)
	{
		if (strcmp(word, array[i]) == 0)
		{
			return i;
		}
		return -1;
	}
}

    这里采用的算法是顺序搜索,虽然简单,但是工作量却与检索数据的数目成正比,因此也被称为线性搜索。

    而对于那些较大的、排好序的算法,我们一般使用二分法进行,二分法将以对数形式进行数据搜索,在数据庞大的情况下有很好的效果。

2.2排序

    如果我们要对某一个数据集进行反复检索,那么先对数组进行排序则是很有必要的。快速排序应该是目前为止最好的排序算法之一。它的实现也很简单:

    我们使用一个基准值(随机选的)将整个数组分为两组:

        “小的”小于基准值的元素、“大的”大于基准值的元素

    递归地这两个组做排序。

    而当这个过程结束的时候,整个数组就已经有序了。快速排序是一种实用而且高效的算法,人们对它做了深入研究,提出了许多变形。在这里要展示的大概是其中最简单的一种实现,但它肯定不是最快的。当然,仅仅是相对的,毕竟神理解递归。

    对于这个算法,网上好多解释,我想说的就是,递归中传递参数的第一个值是数组地址,数组的头地址在不停变化;n也在不停变化,直到递归结束。

#include "stdafx.h"
#include "stdlib.h"
#include <iostream>

using namespace std;

void quicksort(int v[], int n);
void swap(int v[], int i, int j);
int main()
{
	int shuzu[10] = { 8, 1, 2, 6, 4, 5, 3, 7, 0, 9 };
	quicksort(shuzu, 10);
	for (int i = 0; i < 10; i++)
	{
		cout << shuzu[i] ;
	}
    return 0;
}

void quicksort(int v[], int n)
{
	int i, last;
	if (n <= 1)
	{
		return;
	}
	swap(v, 0, rand() % n);
	last = 0;
	for (i = 1; i < n; i++)
	{
		if (v[i] < v[0])
		{
			swap(v, ++last, i);
		}
	}
	swap(v, 0, last);
	quicksort(v, last);
	quicksort(v + last + 1, n - last - 1);//这里加的是地址了
}

void swap(int v[], int i, int j)
{
	int temp;
	temp = v[i];
	v[i] = v[j];
	v[j] = temp;
}

    当然,这种的快速排序依赖于很好的基准值,糟糕的基准值将会使算法的性能大打折扣。有很多更好的、改进的算法,但明显我们并不需要都理解他们。当我们要使用它们的时候,我们要做的就是把库文件包含在我们的程序之中。

2.3库

    对于那些复杂而又常用的代码,C和C++的标准库中已经包含了他们,例如上文提到的排序算法。在C函数库中,排序函数的名字是qsort,在调用qsort时必须为它提供一个比较函数,因为在排序中需要比较两个值。由于这里的值可以是任何类型的,比较函数的参数是两个指向被比较数据的void*指针,在函数里应该把指针强制转换到适当类型,然后提取数据值加以比较,并返回结果(根据比较中的第一个值小于、等于或者大于第二个值,分别返回负数、零或者正数)。

    也就是说,qsort函数需要一个比较函数的入口地址当作函数的输入之一,这个比较函数我们就可以自己进行定义,它可以是比较字符串的,也可以是比较整数的。我们以整数的比较进行示范:

    qsort是定义在头文件<stdlib.h>中的快速排序集合算法,巧妙的设计可以快速的得到想要的结果。在C++中,qsort的函数定义为:

_ACRTIMP void __cdecl qsort(
    _Inout_updates_bytes_(_NumOfElements * _SizeOfElements) void*  _Base,
    _In_                                                    size_t _NumOfElements,
    _In_                                                    size_t _SizeOfElements,
    _In_ int (__cdecl* _PtFuncCompare)(void const*, void const*)
    );

    其中第一个参数为数组名称,第二个是元素个数,第三个是数组中单个元素所占的空间,第四个就是我们输入的比较函数的函数入口地址,使用qsort,我们可以快速的得到从小到大排序好的数组。

qsort(arr, array_number, sizeof(arr[1]), icmp);

    C++中也定义了一个二分搜索函数bsearch,它可以很好的和qsort联系在一起进行使用。qsort类似,bsearch也要求一个指向比较函数的指针 (常用与qsort同样的函数 )bsearch返回一个指针,指向检索到的那个元素;如果没找到有关元素,bsearch返回NULL。在使用的时候,我们定义一个指针来作为bsearch的返回值,这个指针的类型应该与数组的类型一致。

    那么最后,总体的代码就是:

#include "stdafx.h"
#include "stdlib.h"
#include <iostream>

using namespace std;
int icmp(const void *p1, const void *p2);
const int array_number = 10;
int main()
{
	int arr[array_number] = {6, 2, 4, 9, 0, 8, 3, 1, 7, 5};
	int *pItem = NULL;
	int key = 6;
	qsort(arr, array_number, sizeof(arr[1]), icmp);
	pItem = (int *)bsearch(&key, arr, array_number, sizeof(arr[1]), icmp);
	if (pItem != NULL)
	{
		printf("%d is in the array.\n", *pItem);
	}
	else
	{
		printf("%d is not in the array.\n", key);
	}
    return 0;
}
int icmp(const void *p1, const void *p2)
{
	int v1, v2;
	v1 = *(int *)p1;
	v2 = *(int *)p2;
	if (v1 < v2)
	{
		return -1;
	}
	else if (v1 == v2)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值