【算法】二分查找

最近在牛客网刷题,有一道题目是实现二分查找算法,由此便在咖啡店写了段代码,实现这个简单的算法。但同时自己还有一个问题(见最后),希望有朋友能帮忙解答。后期如果自己知道答案,我会自己更新在此。

一. 算法介绍

   优点:比较次数少,查找速度快,平均性能好;

   缺点:要求待查表为有序表,且插入删除困难。

   适用:不经常变动而查找频繁的有序列表。

   时间复杂度:o(log(n))

二. 算法代码实现(C++) 

 1 // BinarySearch.cpp : Defines the entry point for the console application.
 2
 3 #include "stdafx.h"
 4 #include <iostream>
 5
 6 using namespace std;
 7
 8 //compare function
 9 int compare(const void *val1, const void *val2)
10 {
11     int iVal1 = *(int*)val1;
12     int iVal2 = *(int*)val2;
13
14     cout << "Compare: " << iVal1 << ", " << iVal2 << endl;
15
16     if (iVal1 > iVal2)
17     {
18         return 1;
19     }
20     else if (iVal1 == iVal2)
21     {
22         return 0;
23     }
24     else
25     {
26         return -1;
27     }
28 }
29
30 //nel: num of element, width: every element size
31 void *bsearch(const void *key, const void *base, size_t nel, size_t width, int (*compar)(const void*, const void *))
32 {
33     int pos = nel / 2;
34
35     cout << "Position: " << pos << endl;
36
37     int result = (*compar)(key, (int *)base + pos);
38
39     if (pos == 0)
40     {
41         return result == 0 ? (void *)base : NULL;
42     }
43
44     if (result > 0)
45     {
46         return bsearch(key, (int *)base + pos + 1, pos, width, compar);
47     }
48     else if (result == 0)
49     {
50         return (void *)base;
51     }
52     else
53     {
54         return bsearch(key, base, pos, width, compar);
55     }
56 }
57
58 int _tmain(int argc, _TCHAR* argv[])
59 {
60     int array[] = { 1, 3, 5, 6, 11, 13, 17, 29, 44, 66, 79, 99, 111 };
61     int arrayNum = sizeof(array) / sizeof(*array);
62     cout << "Array Element Num: " << arrayNum << endl;
63
64     int searchVal = 13;
65     cout << "Search Value: " << searchVal << endl;
66
67     int *result = (int *)bsearch(&searchVal, array, arrayNum, sizeof(*array), compare);
68
69     cout << "Result: " << (result == NULL ? "Not Found" : "Found") << endl;
70
71     system("pause");
72     return 0;
73 }

运行显示正确。

三. 问题

   这里自己有一个小问题,就是算法接口中的size_t width参数我并没有用到,同时我假设元素都是INT型。请问这里该如何修改,既能用到width,又不用假设元素为特定类型?谢谢。

Best Regards

Kevin Song

时间: 2024-10-11 05:39:46

【算法】二分查找的相关文章

查找算法-二分查找

查找算法-二分查找 标题 二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法.但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列. 过程 首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表.重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找

[经典算法] 二分查找

题目说明: 二分查找法是对一组有序的数字中进行查找,传递相应的数据,进行比较查找到与原数据相同的数据,查找到了返回对应的数组下标,失败返回-1. 题目解析: 二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表. 二分查找可以解决(预排序数组的查找)问题:只要数组中包含T(即要查找的值),那么通过不断缩小包含T的范围,最终就可以找到它.其算法流程如下: 1.一开始,范围覆盖整个数组. 2

检索算法——二分查找

如果要查找的数据是有序的, 二分查找算法比顺序查找算法更高效. function insertionSort(arr) { var temp, inner; for ( var outer = 1; outer < arr.length; ++outer) { temp = arr[outer]; //选中一个值作为临时值,使得其前面的数依次与它进行比较 inner = outer; while (inner > 0 && (arr[inner - 1] >= temp)

算法----二分查找算法

二分查找算法是在有序数组中用到的较为频繁的一种算法,在未接触二分查找算法时,最通用的一种做法是,对数组进行遍历,跟每个元素进行比较,其时间为O(n).但二分查找算法则更优,因为其查找时间为O(lgn),譬如数组{1, 2, 3, 4, 5, 6, 7, 8, 9},查找元素6,用二分查找的算法执行的话,其顺序为: 1.第一步查找中间元素,即5,由于5<6,则6必然在5之后的数组元素中,那么就在{6, 7, 8, 9}中查找, 2.寻找{6, 7, 8, 9}的中位数,为7,7>6,则6应该在7

莫对算法/二分查找 FZU 2072 Count

题目传送门 1 /* 2 题意:问区间内x的出现的次数 3 莫队算法:用一个cnt记录x的次数就可以了 4 还有二分查找的方法 5 */ 6 #include <cstdio> 7 #include <algorithm> 8 #include <cmath> 9 #include <cstring> 10 using namespace std; 11 12 const int MAXN = 1e5 + 10; 13 const int INF = 0x3

八大排序算法二分查找

import java.util.ArrayList;import java.util.Arrays;import java.util.List; import org.junit.Test; public class InsertSort { public static void display(int[] arr){ System.out.print("["); for(int i=0;i<arr.length;i++){ if(i == arr.length-1){ Sys

算法-二分查找

二分查找算法是在有序数组中用到的较为频繁的一种算法,同样是一种很高效的算法,我们最长遇到的判断一个数字是不是在数组中,前提是数组是有效的,通常我们会数组进行遍历,跟每个元素进行比较,其时间为O(n).但二分查找算法则更优,因为其查找时间为O(lgn),譬如数组{0,1, 2, 3, 4, 5, 6, 7, 8, 9},查找元素3,用二分查找的算法执行的话,其顺序为:    1.第一步查找中间元素,即4,由于4>3,则3必然在4之前的数组元素中,那么就在{0,1, 2, 3}中查找,    2.寻

数据结构和算法————二分查找

  二分查找 这些天深刻的体会到了巩固知识的重要性.对数据结构和算法的学习有一年的时间,然后搁置了一年,最后发现都忘记了. 不过还好不是失忆,看了之前做过的笔记,还是能回想起来的. 现在想在写一遍,算是对本子上的笔记做一个备份,更重要的是加深我的印象. 首先说一下二分查找的思想:假设数据是按升序排序的,对于给定值val,从序列的中间位置开始比较. 如果当前位置值等于val,则查找成功: 若val小于当前位置值,则在数列的前半段中查找 若val大于当前位置值,则在数列的后半段中继续查找. 重复以上

oldboy seventeenth day. I love Python. 万恶之神: 递归; 初始算法: 二分查找;

一, 昨日内容讲解 内置函数:重点说几个: max(*args,key=None) min(*args,key=None) zip(*args,key=None) sorted(*args,key=None,reverse=False) reversed() 翻转 返回的是迭代器 filter(key,*args) map(key,*args) 匿名函数: lambda x: x*x二, 作业讲解 三, 今日内容 递归: 设置递归次数: import sys sys.setrecursionli

初级算法:二分查找

如果有这样一个列表,让你从这个列表中找到66的位置,你要怎么做? l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88] 你说,so easy! l.index(66)... 我们之所以用index方法可以找到,是因为python帮我们实现了查找方法.如果,index方法不给你用了...你还能找到这个66么?   上面这个方法就实现了从一个列表中找到66所在的位置了. 但我们现在是怎么找到这个数的