python实现 冒泡排序,快速排序,归并排序,二分查找

冒泡排序
"""
    冒泡排序
    思想:冒泡排序的思想就是通过在无序的序列中,让两个相邻的元素一一对比,
         小的元素左移,大的元素右移.即小的元素逐渐上浮,大的元素逐渐下沉,
         一轮循环下来找到序列的最大值,重复此循环,直到给所有元素排好顺序
"""
import time


def bubble_sort(li):
    # 外层循环控制待确定位置元素的个数
    for j in range(len(li) - 1, 0, -1):
        # 内层循环控制相邻位置的元素对比
        for k in range(j):
            # 当左边元素大于右边元素时
            if li[k] > li[k + 1]:
                # 调换两个元素的位置
                li[k], li[k + 1] = li[k + 1], li[k]
    return li


if __name__ == '__main__':
    t1 = time.time()
    li = [6, 3, 5, 4, 2, 7, 1, 8, 0, 0.2, 9]
    result = bubble_sort(li)
    t2 = time.time()
    print(result)
    print('执行时间是:%.8f秒' % (t2 - t1))

快速排序
"""
    快速排序:
    思想:快速排序的核心思想是分而治之:
        先将序列的第一个元素作为基准值
        创建两个游标,左游标指到基准值后面的第一个元素,右游标指到序列的最后一个元素
        然后左游标右移,右游标左移,当左游标所指的值大于基准值时,左游标停止
        当右游标所指的值小于基准值时,右游标停止,两个元素调换位置
        两个游标循环移动,当左游标索引值大于右游标索引值时,将右游标所指的值与基准值调换位置
        此时第一个基准值就找到了它在序列中的确定位置
        再利用递归思想,循环往复,找到所有元素的确定位置
"""
import time


def quick_sort(li, first, last):
    # 由题意知,当只剩下最后一个待确定的值时,即左右游标指向同一个元素时,此时是退出条件
    # 而下面调用递归的方法,一个是右游标减一的情况,另一个是左游标加一的情况
    # 此时左游标的值都是大于右游标的,所以退出条件如下if语句
    if first > last:
        return

    # 调用函数,取出已确定基准值位置的下标索引
    split_pos = quick(li, first, last)

    # 将序列按照已确定基准值位置的值,分成两部分 
    quick_sort(li, first, split_pos - 1)
    quick_sort(li, split_pos + 1, last)


def quick(li, first, last):
    # 取序列的第一个元素当做基准值
    mid = li[first]
    # 基准值后面的第一个元素作为左游标
    lcur = first + 1
    # 获取右游标
    rcur = last
    sign = True
    while sign:
        # 当左游标小于右游标,且左游标指向值小于基准值时,左游标右移
        while lcur <= rcur and li[lcur] <= mid:
            lcur += 1
        # 当左游标小于右游标,且右游标指向值大于基准值时,左游标右移
        while lcur <= rcur and li[rcur] >= mid:
            rcur -= 1
        # 程序走到这有两种情况
        # 第一:左游标的值大于右游标的值
        # 第二:左游标找到了比基准值大的值,右游标找到了比基准值小的值
        if lcur > rcur:
            # 第一种情况,设置退出条件,调换基准值和右游标的位置
            sign = False
            li[first], li[rcur] = li[rcur], li[first]
        # 第二种情况,调换左右游标的位置
        else:
            li[lcur], li[rcur] = li[rcur], li[lcur]
    # 返回右游标位置,即基准值位置
    return rcur


if __name__ == '__main__':
    t1 = time.time()
    li = [6, 3, 5, 4, 2, 7, 1, 8, 0, 0.2, 9]
    quick_sort(li, 0, len(li) - 1)
    t2 = time.time()
    print(li)
    print('执行时间是:%.8f秒' % (t2 - t1))

归并排序
"""
    归并排序
    思想:归并排序的核心思想是分而治之.
        先分:先将一个无序序列的元素一一的划分成最小单元,
        再和:在按照大小顺序一一的放好位置.
"""
import time


def merge_sort(li):
    # 递归出口, 当分割成最小单元时
    if len(li) == 1:
        return li

    # 将序列分开
    sid = len(li) // 2
    left = li[:sid]
    right = li[sid:]

    # 递归递推过程
    left_list = merge_sort(left)
    right_list = merge_sort(right)

    # 返回值在递归之后,由内向外,回推过程
    return merge(left_list, right_list)


def merge(left_list, right_list):
    # 定义空列表,依次加入元素
    result = []
    # 当两个列表都有元素时,循环加入元素
    while left_list and right_list:
        # 判断两个列表的首个元素大小
        if left_list[0] < right_list[0]:
            # 将首个元素弹出,追加到起初准备的列表中
            result.append(left_list.pop(0))
        else:
            # 将首个元素弹出,追加到起初准备的列表中
            result.append(right_list.pop(0))

    # 当有一个列表为空时,循环结束,将不为空的列表直接合并到结果列表中
    # 注:此处也可以判断哪个列表不为空
    result += left_list
    result += right_list
    return result


if __name__ == '__main__':
    t1 = time.time()
    li = [6, 3, 5, 4, 2, 7, 1, 8, 0, 0.2, 9]
    result = merge_sort(li)
    t2 = time.time()
    print(result)
    print('执行时间是:%.8f秒' % (t2 - t1))

查找算法

二分查找
"""
    二分查找
    思想:二分查找又称折半查找,它的前提条件是序列必须有序,
         二分查找即搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;
         如果中间元素大于或小于要查找元素,则在小于或大于中间元素的那一半进行搜索,
         而且跟开始一样从中间元素开始比较. 如果在某一步骤数组为空,则代表找不到.
         这种算法每一次比较都会使搜索范围缩小一半.
"""


def binary_search(alist, item):
    n = len(alist)
    first = 0
    last = n - 1
    while first <= last:
        mid = (last + first) // 2
        if alist[mid] > item:
            last = mid - 1
        elif alist[mid] < item:
            first = mid + 1
        else:
            return True
    return False


if __name__ == "__main__":
    lis = [2, 4, 5, 12, 14, 23]
    if binary_search(lis, 12):
        print('ok')
    else:
        print('false')

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值