数据结构基础(2) --顺序查找 & 二分查找

顺序查找

适用范围:

没有进行排序的数据序列

缺点:

速度非常慢, 效率为O(N)

//实现
template <typename Type>
Type *sequenceSearch(Type *begin, Type *end, const Type &searchValue)
throw(std::range_error)
{
    if ((begin == end) || (begin == NULL) || (end == NULL))
        throw std::range_error("pointer unavailable");

    for (Type *index = begin; index < end; ++index)
    {
        if (*index == searchValue)
            return index;
    }

    return end;
}

template <typename Type>
Type *sequenceSearch(Type *array, int length, const Type &searchValue)
throw(std::range_error)
{
    return sequenceSearch(array, array+length, searchValue);
}

迭代二分查找

应用范围:

数据必须首先排序,才能应用二分查找;效率为(logN)

算法思想:

譬如数组{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左边的数组元素中,那么只剩下6,即找到了。

二分查找算法就是不断将数组进行对半分割,每次拿中间元素和目标元素进行比较。

//实现:迭代二分
template <typename Type>
Type *binarySearch(Type *begin, Type *end, const Type &searchValue)
throw(std::range_error)
{
    if ((begin == end) || (begin == NULL) || (end == NULL))
        throw std::range_error("pointer unavailable");

    /**注意:此处high为end-1,并不是end
        因为在后续的查找过程中,可能会如下操作 (*high), 或等价的操作
        此时应该访问的是最后一个元素, 必须注意不能对数组进行越界访问!
    */
    Type *low = begin, *high = end-1;
    while (low <= high)
    {
        //计算中间元素
        Type *mid = low + (high-low)/2;
        //如果中间元素的值==要找的数值, 则直接返回
        if (*mid == searchValue)
            return mid;
        //如果要找的数比中间元素大, 则在数组的后半部分查找
        else if (searchValue > *mid)
            low = mid + 1;
        //如果要找的数比中间元素小, 则在数组的前半部分查找
        else
            high = mid - 1;
    }

    return end;
}

template <typename Type>
Type *binarySearch(Type *array, int length, const Type &searchValue)
throw(std::range_error)
{
    return binarySearch(array, array+length, searchValue);
}

递归简介

递归就是递归...(自己调用自己),递归的是神,迭代的是人;

递归与非递归的比较

//递归求解斐波那契数列
unsigned long ficonacciRecursion(int n)
{
    if (n == 1 || n == 2)
        return 1;
    else
        return ficonacciRecursion(n-1) + ficonacciRecursion(n-2);
}
//非递归求解斐波那契数列
unsigned long ficonacciLoop(int n)
{
    if (n == 1 || n == 2)
        return 1;

    unsigned long  first = 1, second = 1;
    unsigned long  ans = first + second;
    for (int i = 3; i <= n; ++i)
    {
        ans = first + second;
        first = second;
        second = ans;
    }

    return ans;
}

递归二分查找

算法思想如同迭代二分查找;

//实现
template <typename Type>
Type *binarySearchByRecursion(Type *front, Type *last, const Type &searchValue)
throw(std::range_error)
{
    if ((front == NULL) || (last == NULL))
        throw std::range_error("pointer unavailable");

    if (front <= last)
    {
        Type *mid = front + (last-front)/2;
        if (*mid == searchValue)
            return mid;
        else if (searchValue > *mid)
            return binarySearchByRecursion(mid+1, last, searchValue);
        else
            return binarySearchByRecursion(front, mid-1, searchValue);
    }

    return NULL;
}

template <typename Type>
int binarySearchByRecursion(Type *array, int left, int right, const Type &searchValue)
throw (std::range_error)
{
    if (array == NULL)
        throw std::range_error("pointer unavailable");

    if (left <= right)
    {
        int mid = left + (right-left)/2;
        if (array[mid] == searchValue)
            return mid;
        else if (searchValue < array[mid])
            return binarySearchByRecursion(array, left, mid-1, searchValue);
        else
            return binarySearchByRecursion(array, mid+1, right, searchValue);
    }

    return -1;
}

小结:

其实C++ 的STL已经实现好了std::binary_search(),在用的时候我们只需调用即可, 但是二分算法的思想还是非常重要的, 在求解一些较为复杂的问题时, 我们时常能够看到二分的身影.

时间: 2024-10-13 04:34:00

数据结构基础(2) --顺序查找 & 二分查找的相关文章

9-2-折半查找/二分查找-查找-第9章-《数据结构》课本源码-严蔚敏吴伟民版

课本源码部分 第9章  查找 - 折半查找/二分查找 ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接??? <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+习题集解析使用说明        课本源码合辑  链接??? <数据结构>课本源码合辑        习题集全解析  链接??? <数据结构题集>习题解析合辑        本源码引入的文件  链接? Base.c        相关测试数据下载  链接? 数据包      

leetcode旋转数组查找 二分查找的变形

http://blog.csdn.net/pickless/article/details/9191075 Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). You are given a target value to search. If found in the array return it

查找 —— 二分查找[递归+非递归]

二分查找 二分查找是对一组有序序列进行查找.根据要查找的k和序列中间元素比较,动态的移动查找范围.以对折的方式缩小查找范围. 递归方式: def binarySearch(A,left,right,k): if left<= right: mid =(left+right)//2 if A[mid] == k: return mid if A[mid]>k: return binarySearch(A,left,mid-1,k) #此处要返回函数运行结果而不是仅仅调用函数 else: retu

PHP实现文本快速查找 - 二分查找

PHP实现文本快速查找 - 二分查找法 起因 先说说事情的起因,最近在分析数据时经常遇到一种场景,代码需要频繁的读某一张数据库的表,比如根据地区ID获取地区名称.根据网站分类ID获取分类名称.根据关键词ID获取关键词等.虽然以上需求都可以在原始建表时,通过冗余数据来解决.但仍有部分业务存的只是关联表的ID,数据分析时需要频繁的查表. 所读的表存在共同的特点 数据几乎不会变更 数据量适中,从一万到100多万,如果全加载到内存也不太合适. 纠结的地方 在做数据分析时,需要十分频繁的读这些表,每秒有可

查找算法(I) 顺序查找 二分查找 索引查找

查找 本文为查找算法的第一部分内容,包括了基本概念,顺序查找.二分查找和索引查找.关于散列表和B树查找的内容,待有空更新吧. 基本概念 查找(search)又称检索,在计算机上对数据表进行查找,就是根据所给条件查找出满足条件的第一条记录(元素)或全部记录. 若没有找到满足条件的记录,则返回特定值,表明查找失败:若查找到满足条件的 第一条记录,则表明查找成功,通常要求返回该记录的存储位置或记录值本身,以便进行进一步处理:若需要查找到满足条件的所有记录,则可看做在多个区间内连 续查找到满足条件的第一

数据结构与算法实践 之 二分查找初识

今天起,我要对数据结构和基本的算法进行一些简单的复习,并在复习的基础上对其进行深入的挖掘.这篇文章先对二分查找进行一个简要的复习,在之后的文章中会对其进行深入的学习. 二分查找又叫折半查找,是最基本的几种查找算法之一.简单的看,二分法查找主要应用于在一个有序数列中进行元素的查找,其基本思路是,先用我们要查找的元素与这个有序数列中的中间位置的元素进行比较(在此我们姑且称这个元素为"中间位置元素"吧,至于这个元素怎么求我在后面会详细说明),如果相等,则返回这个"中间位置元素&qu

【基础算法】冒泡排序+二分查找法

1.思考题 (1)有12颗球,1颗是9克,其余的都是10克,怎样在天平上称三次找出9克的那颗质量小的球? 答:第一次:把12颗球分成两半,一半6颗,在天平上称,取质量小的一边: 第二次:把6颗球分成两半,一半三颗,也取质量小的一边: 第三次:取三颗球中任一两颗去称,如果质量相等,那么没有称的那一颗就是质量最小的一颗(9克),如果两颗质量不想等,取质量小的一颗也可以取到. (2)有1024个人,有一个人血液有病毒,而999个人没有病毒,化验一个人的血液需要10分钟,怎么用最短的时间找出有血液病毒的

数据结构与算法-LeetCode练习二分查找应用

LeetCode 153. Find Minimum in Rotated Sorted Array 查找循环排序数组的最小元素(循环排序数组可以理解,一个环状数组(0,1,2,4,5,6,7),从其中一个元素断开后4,5,6,7,0,1,2). 查找一个数组的最小原始,我们知道最简单的方式就是循环遍历其中数字,时间复杂度O(n)肯定能找到这个元素.我们看循环排序数组的结构,我们发现我们的数组还不完全是一个乱序数组,我们通过分析数组的规律,我们可以看的出,我们的数组还是局部有序的,我们的数组可以

0518Python基础-内置函数-二分查找

1.昨日内容回顾 len() 测试个数 eval() 去掉字符串的引号,返回内部结果 eval('1+1') ---> 2 exec() 去掉字符串的引号,执行内部代码 ret = ''' if True: print(666) ''' exec(ret) range next() iter() reversed() 返回的是迭代器 sorted(iterable,key,reverse)  return list       key zip(iter1,iter2,iter3....) 拉链方