查找操作及分类
操作
分类:
“电话号码簿”和“字典”都可 看作一张查找表, 而按“姓”或者“字母”查询则是按索引查询!
分块查找的算法分两步进行,首先确定所查找的节点属于哪一块,即在索引表中查找其所在的块, 然后在块内查找待查询的数据。由于索引表是递增有序的,可采用二分查找,而块内元素是无序 的,只能采用顺序查找。(块内元素较少,则不会对执行速度有太大的影响)
二分查找法实质上是不断地将有序数据集进行对半分割,并检查每个分区的中间元素。再重 复根据中间数确定目标范围并递归实行对半分割,直到中间数等于待查找的值或是目标数不在搜 索范围之内!
测试源码源码:
#include
#include
int int_compare(const void *key1, const void *key2){
const int *ch1 = (const int *)key1;
const int *ch2 = (const int *)key2;
return (*ch1-*ch2);
}
int char_compare(const void *key1, const void *key2){
const char *ch1 = (const char *)key1;
const char *ch2 = (const char *)key2;
return (*ch1-*ch2);
}
int BinarySearch(void *sorted, int len, int elemSize, void *search, int (*compare)(const void *key1, const void *key2))
{
int left = 0, right = 0, middle = 0;
/*初始化 left 和 right 为边界值*/
left = 0;
right = len - 1;
/* 循环查找,直到左右两个边界重合*/
while(left <= right){
int ret = 0;
middle = (left + right) /2 ;
ret = compare((char *)sorted+(elemSize*middle), search);
if(ret == 0){
/*middle 等于目标值*/
/*返回目标的索引值 middle*/
return middle;
}else if( ret > 0){
/*middle 大于目标值*/
/*移动到 middle 的左半区查找*/
right = middle - 1;
}else {
/*middle 小于目标值*/
/*移动到 middle 的右半区查找*/
left = middle + 1;
}
}
return -1;
}
int main(void){
int arr[]={
1, 3, 7, 9, 11};
int search[] = {
-1, 0, 1, 7 , 2, 11, 12};
printf("整数查找测试开始。。。\n");
for(int i=0; i<sizeof(search)/sizeof(search[0]); i++){
int index = BinarySearch(arr, sizeof(arr)/sizeof(arr[0]), sizeof(int), &search[i], int_compare);
printf("searching %d, index: %d\n",search[i], index);
}
char arr1[]={
'a','c','d','f','j'};
char search1[] = {
'0', 'a', 'e', 'j' , 'z'};
printf("\n 字符查找测试开始。。。\n");
for(int i=0; i<sizeof(search1)/sizeof(search1[0]); i++){
int index = BinarySearch(arr1, sizeof(arr1)/sizeof(arr1[0]), sizeof(char), &search1[i], char_compare);
printf("searching %c, index: %d\n",search1[i], index);
}
system("pause");
return 0;
}
用穷举算法解决问题,通常可以从两个方面进行分析:
并发的基本概念:
假设我们要从很大的一个无序的数据集中进行搜索,假设我们的机器可以一次性容纳这么多 数据。从理论上讲,对于无序数据,如果不考虑排序,已经很难从算法层面优化了。而利用 上面我们提到的并行处理思想,我们可以很轻松地将检索效率提升多倍。
具体实现思路如下: 将数据分成 N 个块,每个块由一个 线程来并行搜索。
线程演示代码:
#include
#include
#include
#include
#define TEST_SIZE (1024*1024*200)
#define NUMBER 20
DWORD WINAPI ThreadProc(void* lpParam) {
for (int i = 0; i < 5; i++) {
printf("进程,我来了!\n");
Sleep(1000);
}
return 0;
}
int main(void) {
DWORD threadID1;//线程 1 的身份证
HANDLE hThread1;//线程 1 的句柄
DWORD threadID2;//线程 2 的身份证
HANDLE hThread2;//线程 2 的句柄
printf("创建线程... ... \n");
//创建线程 1
hThread1 = CreateThread(NULL, 0, ThreadProc, NULL, 0, &threadID1);
//创建线程 2
hThread2 = CreateThread(NULL, 0, ThreadProc, NULL, 0, &threadID2);
WaitForSingleObject(hThread1, INFINITE);
WaitForSingleObject(hThread2, INFINITE);
printf("进程欢迎线程归来!\n");
system("pause");
return 0;
}