【Day1】算法图解——学习笔记

一 算法简介

  1. 二分查找示例:

def binary_search(list, item):
    low = 0
    high = len(list)1
    while low <= high:
        mid = (low + high)/2
        guess = list[mid]
        if guess == item:
            return mid
        if guess > item:
            high = mid - 1
            else:
                low = mid + 1
                return None
            my_list = [1, 3, 5, 7, 9]
            print binary_search(my_list, 3) # => 1
            print binary_search(my_list, -1) # => None

  1. 对数:

    2^3 = 8,log 8 = 3。 大O表示法讨论运行时间时,常用对数来计算

  2. 大O表示法

    • 让你能够比较操作数,它指出了算法运行时间的增速。
    • 大O法还能指出最糟情况下的运行时间
  3. 一些常见的大O运行时间

    • O(log n),也叫对数时间,这样的算法包括二分查找。
    • O(n),也叫线性时间,这样的算法包括简单查找。
    • O(n * log n),这样的算法包括第4章将介绍的快速排序——一种速度较快的排序算法。
    • O(n2),这样的算法包括第2章将介绍的选择排序——一种速度较慢的排序算法。
    • O(n!),这样的算法包括接下来将介绍的旅行商问题的解决方案——一种非常慢的算法。

    需要注意的是,算法的速度指的并非时间,而是操作数的增加速度。

    一般情况下,算法速度O(log n)>O(n)>O(n*log n)>O(n2)>O(n!)

  4. 旅行商问题

    旅行商前往各地,寻找在最短路径,此算法的复杂度为: O(n!)

    可他别无选择。这是计算机科学领域待解的问题之
    一。对于这个问题,目前还没有找到更快的算法,有些很聪明的人认为这个问题根本就没有更巧
    妙的算法。面对这个问题,我们能做的只是去找出近似答案,更详细的信息请参阅第10章。

  5. 小结

    • 二分查找的速度比简单查找快得多。
    • O(log n)比O(n)快。需要搜索的元素越多,前者比后者就快得越多。
    • 算法运行时间并不以秒为单位。
    • 算法运行时间是从其增速的角度度量的。
    • 算法运行时间用大O表示法表示。

二 选择排序

1. 数组和链表

  1. 数组

    • 数组在内存中的地址是相连的,需要改变数组时,只能通过申请一个新的内存地址来解决
    • 遇到元素超过容量的时候就需要频繁扩容,预留容量开辟大空间数组可以解决问题,但是
      • 额外内存用不上时,浪费内存
      • 超过上限的情况依旧需要开辟新的地址
  2. 链表

    • 链表中的元素可存储在内存的任何地方。
    • 链表的每个元素都存储了下一个元素的地址,从而使一系列随机的内存地址串在一起。
  3. 数组趣闻

排行榜网站使用卑鄙的手段来增加页面浏览量。它们不在一个页面中
显示整个排行榜,而将排行榜的每项内容都放在一个页面中,并让你单击
Next来查看下一项内容。例如,显示十大电视反派时,不在一个页面中显
示整个排行榜,而是先显示第十大反派(Newman)。你必须在每个页面中
单击Next,才能看到第一大反派(Gustavo Fring)。这让网站能够在10个页
面中显示广告,但用户需要单击Next 九次才能看到第一个,真的是很烦。

  1. 数组和链表的特点

    • 数组查询快,修改慢

    • 链表查询慢,修改快

    • 运行时间数组链表
      查询O(1)O(n)
      修改O(n)O(1)
  2. 数组和列表相结合

    • 数组作为索引,再结合链表,也就是散列表(哈希表),是大型网站使用的数据结构。
    • 这种结构下查询速度略慢于数组,但是修改速度和链表相当

2. 选择排序

  • 选择排序问题:

    • 一个双列结构(键值对),要根据值的大小进行自然排序,首次遍历一次选出最小的,第二次遍历选出第二小的,以此类推,最后排序结束。
  • 操作数:

    O(n)意味着对列表中每个元素都操作一次,每次遍历的次数为n,一共有n个元素,因此要遍历n次。所以

    需要的总操作时间为 O( n * n ) ,即 O(n^2)

    第一次需要检查n个元素,但随后检查的元素
    数依次为n - 1, n - 2, …, 2和1。平均每次检查的元素数为1/2 × n,因此运行时间为O(n × 1/2 × n)。
    但大O表示法省略诸如1/2这样的常数(有关这方面的完整讨论,请参阅第4章),因此简单地写
    作O(n × n)或O(n2)。

    选择排序是一种灵巧的算法,但其速度不是很快。快速排序是一种更快的排序算法,其运行
    时间为O(n log n),这将在下一章介绍。

  • 示例代码:

def findSmallest(arr):
    smallest = arr[0]
    smallest_index = 0
    for i in range(1, len(arr)):
        if arr[i] < smallest:
            smallest = arr[i]
            smallest_index = i
            return smallest_index
        #现在可以使用这个函数来编写选择排序算法了。
def selectionSort(arr):
   newArr = []
   for i in range(len(arr)):
      smallest = findSmallest(arr)
      newArr.append(arr.pop(smallest))
      return newArr
   print selectionSort([5, 3, 6, 2, 10])
  • python中的pop()方法可以移除列表中的一个元素并将其返回
  • 因此每次对列表进行遍历,得到最小值的索引,将其pop,如此往复,添加到新的列表中,就完成了选择排序(每次选择一个元素进行操作)

3. 小结

  • 计算机内存犹如一大堆抽屉。
  • 需要存储多个元素时,可使用数组或链表。
  • 数组的元素都在一起。
  • 链表的元素是分开的,其中每个元素都存储了下一个元素的地址。
  • 数组的读取速度很快。
  • 链表的插入和删除速度很快。
  • 在同一个数组中,所有元素的类型都必须相同(都为int、double等)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值