归并排序+二分查找

目录

 

归并排序

归并排序的思想

跑不通但是理解了的代码

跑通了且理解来了的代码

常见算法的时间复杂度比较

二分查找


归并排序

归并排序的思想

把一个无序序列从中间分开,知道每个字列表只剩下一个元素

然后再做合并,合并的过程中从小到大排序,课上老师讲的代码跑不通,还不知道哪里有问题,但是思想是理解了

跑不通但是理解了的代码

#总是报错,我也无语了
'''
def merge_sort(li):

    n = len(li)
    if n <= 1:
        return li
    mid = n // 2

    #left采用归并排序后形成的有序的新的列表

    left_list = merge_sort(li[:mid])
    #right采用归并排序后形成的有序的新的列表
    right_list = merge_sort(li[mid:])

    #将两个有序的子系列合并为一个新的整体
    #merge(left, right)
    left_pointer, right_pointer = 0, 0
    result = []

    while left_pointer < len(left_list) and right_pointer < len(right_list):
        if left_list[left_pointer] <= right_list(right_pointer):
            result.append(left_list[left_pointer])
            left_pointer += 1
        else:
            result.append(right_list[right_pointer])
            right_pointer += 1


    #退出循环的时候,把左列表或者右列表的剩余内容都加进去
    result += left_list[left_pointer:]
    result += right_list[right_pointer:]

    return result


if __name__ == "__main__":
    li = [54, 26, 93, 13, 77,  31, 55, 28]
    print(li)
    li = merge_sort(li)
    print(li)
'''


'''

n = 9 n // 2 =4 时 left_li = merge_sort[54, 26, 93, 13]
      n // 2 = 2时 left_li = merge_sort[54, 26]
      n // 2 = 1时候 left_li = merge_sort[54]
      n = 1 此时要把alist返回 即返回left_li = [54]
                                 right_li = [26]
      进入函数体之后,需要把两个列表进行合并,合并完之后是[26, 54]
      返回result = [26, 54] left_li = merge_sort[54, 26] 的执行结果就是[26, 54]
      然后返回上一级left_li = merge_sort[54, 26, 93, 13]中,进行right_li 的合并
      right_li =  merge_sort[93,17]
                                 left_li = [93]
                                 right_li = [17]
                                                                
      执行的结果为[17, 93] 
      然后将[26, 54] 和 [17, 93]进行合并
      [17, 26, 54, 93]
      继续执行,将[77,  31, 55, 28]这个列表进行切片操作之后,把整个过程重复以便,得到的结果为[28,31,55,77]
              
'''

跑通了且理解来了的代码

#先定义merge函数
def merge(L, R):
    n = len(L) + len(R)
    L.append(float("inf"))
    R.append(float("inf"))
    i = 0
    j = 0
    A = []
    for k in range(0, n):
        if L[i] <= R[j]:
            A.append(L[i])
            i = i+1
        else:
            A.append(R[j])
            j = j+1
    return A


#自定义merge_sort函数
def merge_sort(A):
    l = len(A)
    if l <= 1:
        return A
    else:
        mid = l//2
        print(mid)
        left = merge_sort(A[0:mid])
        right = merge_sort(A[mid:])
        return merge(left, right)

if __name__ == "__main__":
    li = [54, 26, 93, 13, 77,  31, 55, 28]
    print(li)
    li = merge_sort(li)
    print(li)
#[13, 26, 28, 31, 54, 55, 77, 93]

常见算法的时间复杂度比较

二分查找

两个条件:(1)是已经排序好的序列;(2)支持索引,就是按顺序存放,也就是只能作用于顺序表

把有序列表从中间分开,mid =(第一个位置+列表最后一个位置) // 2 然后比较中间位置的数值和要查找的数值的大小

#二分查找的两个大前提:1、有序序列;2、顺序表
#递归版本
def binary_search(alist, item):
    '''二分查找'''
    n = len(alist)
    if n > 0:
        mid = n // 2
        if alist[mid] == item:
            return True
        elif item < alist[mid]:
            return binary_search(alist[:mid], item)  #这里要返回一个结果!前面一定要有return
        else:
            return binary_search(alist[mid+1:], item)
    return False



#非递归版本
def binary_search2(alist, item):
    '''二分查找'''
    n = len(alist)
    first = 0
    last = n-1
    while first <= last:
        mid = (first + last) // 2
        if alist[mid] == item :
            return True
        elif alist[mid] > item:
            last = mid - 1
        else:
            first = mid + 1
    return False



if __name__ == "__main__":
    li = [17, 20, 26, 31, 44, 54, 55, 77, 93]
    print(binary_search(li, 20))
    print(binary_search(li, 100))
    print(binary_search2(li, 55))
    print(binary_search2(li, 200))

'''
True
False
True
False
'''

#最优时间复杂度:O(1)
#最坏时间复杂度:O(logn)

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值