20210330-20210329 第6部分 6. 排序与搜索(下)

本文介绍了归并排序的分治思想及其实现代码,详细解析了时间复杂度,并与其他常见排序算法进行了效率比较。同时,讲解了二分查找的概念、非递归和递归实现,探讨了其时间复杂度。

6. 排序与搜索

6.7 并归排序

归并排序是采用分治法的一个非常典型的应用。归并排序的思想就是先递归分解数组,再合并数组。

将数组分解成最小之后,然后合并两个有序数组,基本思路是比较两个数组的最前面的数,谁小就先取谁,取了后相应的指针就往后移一位。然后再比较,直至一个数组为空,最后把另一个数组的剩余部分复制过来即可。

归并排序的分析

在这里插入图片描述

实现代码
def merge_sort(alist):
    if len(alist) <= 1:
        return alist
    # 二分分解
    num = len(alist) // 2
    # left是采用并归排序后形成的新的有序列表,right同理
    left = merge_sort(alist[:num])
    right = merge_sort(alist[num:])
    # 合并
    return merge(left,right)


def merge(left, right):
    """合并操作,将两个有序数组left[]和right[]合并成一个大的有序数组"""
    # left与right的下标指针
    l, r = 0, 0
    result = []
    while l<len(left) and r<len(right):
        if left[l] <= right[r]:  # 只要这里是<=,算法就是稳定的
            result.append(left[l])
            l += 1
        else:
            result.append(right[r])
            r += 1
    result += left[l:]
    result += right[r:]
    return result


alist = [54,26,93,17,77,31,44,55,20]
sorted_alist = merge_sort(alist)
print(sorted_alist
时间复杂度
  • 最优时间复杂度:O(nlogn)
  • 最坏时间复杂度:O(nlogn)
    注:虽然并归算法的时间复杂度小一些,但是这个算法因为运行过程中不断产生新的列表,所以有额外的空间开销。
  • 稳定性:稳定

6.8 常见排序算法效率比较

在这里插入图片描述
注1:堆排序建立在二叉树思想的基础上。:
注2:快速排序算法中,列表本身用的空间是O(1);但是因为递归,栈的空间要占用O(logn),所以整个快速排序算法的辅助空间不为O(1)。Me:这里递归为什么占用的空间是O(logn)还没完全搞清楚,我用等比数列求和算下来是2x(x代表代码量),后面有空再深入分析。

6.9 搜索

搜索是在一个项目集合中找到一个特定项目的算法过程。通常搜索的答案根据该项目是否存在,是真的或假的。 搜索的几种常见方法:顺序查找、二分法查找、二叉树查找、哈希查找。

二分法查找

二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难(增删需要移动大量的节点)。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
在这里插入图片描述

二分法查找实现代码(非递归实现)
def binary_search(alist, item):
    first = 0
    last = len(alist) - 1
    while first <= last:
        midpoint = (first + last) // 2
        if alist[midpoint] == item:
            return True
        elif item < alist[midpoint]:
            last = midpoint - 1
        else:
            first = midpoint + 1
    return False


testlist = [0, 1, 2, 8, 13, 17, 19, 32, 42]
print(binary_search(testlist, 3))
print(binary_search(testlist, 13))
二分法查找实现代码(递归实现)
def binary_search(alist, item):
    if len(alist) == 0:
        return False
    else:
        midpoint = len(alist) // 2
        if alist[midpoint] == item:
            return True
        else:
            if item < alist[midpoint]:
                return binary_search(alist[:midpoint], item)
            else:
                return binary_search(alist[midpoint + 1:], item)


testlist = [0, 1, 2, 8, 13, 17, 19, 32, 42]
print(binary_search(testlist, 3))
print(binary_search(testlist, 13))
时间复杂度
  • 最优时间复杂度:O(1)
  • 最坏时间复杂度:O(logn)
源码直接下载地址: https://pan.quark.cn/s/d280357b18e5 在网页构建领域中,HTML5被视为当代网页工程的基础规范,其问世显著增强了页面的视觉表现力用户互动性。本工程致力于运用HTML5技术开发一个电视剧信息展示页面,目的是呈现诸如剧名、演员构成、故事梗概等电视剧关键资料。接下来将深入阐释如何借助HTML5的结构化组件和样式管理功能达成此项目目标。 我们必须掌握HTML5的核心框架。一个规范的HTML5文档一般包含`<!DOCTYPE html>`声明、`<html>`根标记、`<head>`头部标记和`<body>`主体标记。在头部区域,可以配置网页的基本元数据,例如字符集设定、页面标题等。在主体部分,将具体构建电视剧信息列表的内容。 电视剧展示页面通常包含多个条目,每个条目对应一部电视剧。HTML5中的`<section>`标记用于内容模块化,适合表示单个电视剧的详细信息区域。每个`<section>`内部,可使用`<h2>`标题标记显示剧名,`<img>`图像标记插入宣传剧照,`<p>`段落标记呈现剧情介绍,而`<ul>`无序列表`<li>`列表项标记则用于罗列演员阵容。 为了优化页面布局,需要借助CSS(层叠样式表)进行样式管理。HTML5引入了创新的CSS选择器布局模型,例如Flexbox和Grid,使页面布局更加灵活多变。在此场景下,可以利用Flexbox为电视剧信息列表实现自适应布局,保障在不同设备尺寸下均能呈现理想视觉效果。具体操作时,可将`<section>`标记设定为Flex容器,通过`display: flex;`属性,并运用`justify-content`和`align-items`属性调整子元素的对...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值