数据结构学习2:查找算法之顺序查找和二分查找原理及Python实现

1. 顺序查找

(1)原理:顺序查找又称为线性查找,是一种最简单的查找方法。

      从表的一端开始,向另一端逐个按要查找的值key 与关键码key进行比较,若找到,查找成功,并给出数据元素在表中的位置;若整个表检测 完,仍未找到与关键码相同的key值,则查找失败,给出失败信息。

     说白了就是,从头到尾,一个一个地比,找着相同的就成功,找不到就失败。很明显的缺点就是查找效率低。

【适用性】:适用于线性表的顺序存储结构和链式存储结构。

 平均查找长度=(n+1)/2.

【顺序查找优缺点】:

 缺点:是当n 很大时,平均查找长度较大,效率低;

 优点:是对表中数据元素的存储没有要求。另外,对于线性链表,只能进行顺序查找。


(2)时间复杂度:有可能第1个,第2个位置就找到了,也有可能遍历到最后一个位置(n)才找到,所以每次所要查找比较的平均次数是

       (1+2+3+ ... + n) / n = (n+1) / 2, 所以时间复杂度是O(n)

(3)Python实现代码

def seqSearch(myList, value):
    for i in range(len(myList)):
        if myList[i] == value:
            isFound = True
            print('已找到数值',value,'在第',i,'个位置')
            return i
    print('没有找到数值',value)
    return -1

list1 = [2,5,7,9,100,88,292,39]
idx1 = seqSearch(list1, 88)
idx2 = seqSearch(list1, 99)
print(idx1,idx2)

已找到数值 88 在第 5 个位置
没有找到数值 99
5 -1


2. 二分查找二分查找的前提是元素有序(一般是升序), 如果是乱序的,要先进行排序。

(1)原理

       二分查找的基本思想是拿中间元素A[m]与要查找的元素x进行比较,如果相等,则已经找到,如果A[m]比x大,那么要找的元素一定在A[m]前边,如果A[m]比x小,那么要找的元素一定在A[m]后边。没进行一次查找,数组规模减半。反复将子数组规模减半,直到发现要查找的元素,或者当前子数组为空。

(2)时间复杂度:二分查找的时间复杂度是O(lgn)

       设总共有n个元素,每次查找的区间大小就是n,n/2,n/4,…,n/2^k(接下来操作元素的剩余个数),其中k就是循环的次数,每次循环都比较value和中间值的大小.
       由于n/2^k取整后>=1,即令n/2^k=1,可得k=log2n,(是以2为底,n的对数),所以时间复杂度可以表示O(logn)

(3)Python实现代码: 非递归实现和递归实现

# 非递归实现
def binSearch(myList, value):
    "二分排序法的非递归实现实现,要确保myList是有序的(默认升序)"
    start = 0; end = len(myList) - 1
    
    while start <= end:
        # start > end 时说明当二分后的列表长度为1时,如start = 0, end = 0,即查找到第1个数字时,仍没有找到value,此时执行
        # end = mid - 1后end = -1 故有start > end; 又或者start == len(myList)-1,即查找到最末尾一个数字时,仍没有找到value,
        # 此时执行start = mid + 1后start = len(myList),故有start > end. 即在整个列表内都没有找到value,循环结束,返回-1
        mid = int((start + end) / 2)
        if myList[mid] == value:
            return mid             # 找到value值,返回位置
        elif myList[mid] > value:
            end = mid - 1
        else:
            start = mid + 1

    return -1;
# 递归实现
def RecurBinSearch(myList,start,end, value):
    "二分排序法的递归实现,要确保myList是有序的(默认升序)"
    mid = int((start + end) / 2)

    if (len(myList) == 0 |  value < myList[start] | value > myList[end]):
        return -1

    if myList[mid] == value:
        return mid
    elif myList[mid] > value:
        return RecurBinSearch(myList, start, mid - 1, value)
    elif myList[mid] < value :
        return RecurBinSearch(myList, mid + 1, end, value)

测试查找算法:

# 测试
list1 = [2,3,5,6,8,9,12,33,45,67,88,99]
index1 = binSearch(list1, 2)
print(index1)

endIdx = len(list1) - 1
index2 = RecurBinSearch(list1,0,endIdx, 67)
print(index2)

0
9



https://blog.csdn.net/junbin1011/article/details/53488353


参考文章:

猜你喜欢

转载自blog.csdn.net/zhuzuwei/article/details/80586187