常见简单算法-Python实现(2) 二分法搜索、合并两个已排序的表



声明:
本文给出 二分法搜索、合并两个已排序表 的算法的Python实现方法和运行结果;
代码有问题或疑惑下方评论,有错勿喷;更多大学简单算法的实现进我博客;


1. 二分法搜索 binary_search

程序代码
# 二分搜索
# 输入:按从小到大顺序排列的数组A,要搜索的数num
# 输出:如果搜索到,则输出该元素的位置,如果没有搜索到,则输出“没有搜索到该值”;并且输出比较次数count_compare

import math

def binary_search(A,num):

    n = len(A)               # n            数组长度
    low = 0                  # low          指向低地址的指针
    high = n-1               # high         指向高地址的指针
    num_location = -1        # num_location 要搜索的元素的位置
    count_compare = 0        


    while high - low > 1 and num_location == -1:

        mid = math.floor( (low + high)/2 )          # mid 指向low和high中心元素的指针,floor表示向下取整

        if A[mid] == num:
            num_location = mid                      # 当且仅当找到要搜索的值,才会改变num_location的值 
        elif A[mid] <= num:
            low = mid
        else:
            high = mid
        
        count_compare = count_compare + 1

        # print('第i趟搜索:',count_compare)
        # print('mid ',mid);print('low ',low);print('high ',high)


    if high - low == 1:                             # 如果指针指向相邻的两个元素,那么要搜索的值要么是这两个元素其一,要么不存在
        if A[low] == num:
            num_location = low
        elif A[high] == num:
            num_location = high
        count_compare = count_compare + 1
    # 注:极少数情况下,若最后两个数相等,且都为要搜索的数,则通过此if判断语句后,num_location会变为high,也就是只会输出后面的元素的位置


    print('\n 输入的数组为:',A)
    print(' 要搜索的数为:',num)
    
    if num_location == -1:                          # 说明没有搜索到要搜索的值
        print('\n 没有搜索到该值')
        print(' 比较次数为:', count_compare)
    else:
        print('\n 在该数组的位置:', num_location+1)
        print(' 比较次数为:', count_compare)



# 主函数
# 在此修改数据
A = [-39, -22, -1, 5, 12, 21, 33, 56, 56, 76, 92, 92, 110, 999]
num = 110
binary_search(A,num)

运行结果
 输入的数组为: [-39, -22, -1, 5, 12, 21, 33, 56, 56, 76, 92, 92, 110, 999]
 要搜索的数为: 110

 在该数组的位置: 13
 比较次数为: 4
 输入的数组为: [-39, -22, -1, 5, 12, 21, 33, 56, 56, 76, 92, 92, 110, 999]
 要搜索的数为: 0

 没有搜索到该值
 比较次数为: 5
 输入的数组为: [-39, -22, -1, 5, 12, 21, 33, 56, 56, 76, 92, 92, 110, 999]
 要搜索的数为: -1000

 没有搜索到该值
 比较次数为: 4


2. 合并两个已排序的表 merge

程序代码
# 合并两个已排序的序列 merge
# 输入:已排序的数组A1、A2
# 输出:合并且排好序的数组B

def merge(A1,A2):

    a1 = 0                           # 指向数组A1的指针
    a2 = 0                           # 指向数组A2的指针
    n1 = len(A1)-1                   # 数组A1的最大下标
    n2 = len(A2)-1                   # 数组A2的最大下标
    B = [ 0 for i in range(n1+n2+1)] # 数组B用于存放合并结果,长度为数组A1,A2的长度之和
    b = 0                            # 指向数组B 的指针

    while a1<=n1 and a2<=n2:
        if A1[a1] <= A2[a2]:
            B[b] = A1[a1]
            b = b+1
            a1 = a1+1
        else:                        # A1[a1] > A2[a2]
            B[b] = A2[a2]
            b = b+1
            a2 = a2+1
        print(B)                     # 打印填充数组B的过程
    return B


# 函数调用
# 在此修改数据
A1 = [-34,-22,-11,2,9,20,30,78,243]
A2 = [-88,-20,-2,29,30,66,129]
print('\n 合并结果为:', merge(A1,A2) )

运行结果
[-88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[-88, -34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[-88, -34, -22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[-88, -34, -22, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[-88, -34, -22, -20, -11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[-88, -34, -22, -20, -11, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[-88, -34, -22, -20, -11, -2, 2, 0, 0, 0, 0, 0, 0, 0, 0]
[-88, -34, -22, -20, -11, -2, 2, 9, 0, 0, 0, 0, 0, 0, 0]
[-88, -34, -22, -20, -11, -2, 2, 9, 20, 0, 0, 0, 0, 0, 0]
[-88, -34, -22, -20, -11, -2, 2, 9, 20, 29, 0, 0, 0, 0, 0]
[-88, -34, -22, -20, -11, -2, 2, 9, 20, 29, 30, 0, 0, 0, 0]
[-88, -34, -22, -20, -11, -2, 2, 9, 20, 29, 30, 30, 0, 0, 0]
[-88, -34, -22, -20, -11, -2, 2, 9, 20, 29, 30, 30, 66, 0, 0]
[-88, -34, -22, -20, -11, -2, 2, 9, 20, 29, 30, 30, 66, 78, 0]
[-88, -34, -22, -20, -11, -2, 2, 9, 20, 29, 30, 30, 66, 78, 129]

 合并结果为: [-88, -34, -22, -20, -11, -2, 2, 9, 20, 29, 30, 30, 66, 78, 129]


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值