博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
算法 初识
阅读量:5020 次
发布时间:2019-06-12

本文共 10304 字,大约阅读时间需要 34 分钟。

什么是算法 如何理解算法?

算法就是对问题进行处理且求解的一种实现思路或者思想。

  • 一个常胜将军在作战之前都会进行战略的制定,目的是为了能够在最短的时间切成本消耗最低的情况下获取最终的胜利。如果将编码作为战场,则程序员就是这场战役的指挥官,你如何可以将你的程序可以在最短且消耗资源最小的情况下获取最终的执行结果呢?算法就是我们的策略!

什么是算法分析?

  • 刚接触编程的学生经常会将自己编写的程序和别人的程序做比对,获取在比对的过程中会发现双方编写的程序很相似但又各不相同。那么就会出现一个有趣的现象:两组程序都是用来解决同一个问题的,但是两组程序看起来又各不相同,那么哪一组程序更好呢?
  • a+b+c = 1000 a2 + b2 = c**2 (a,b,c均为自然数),求出a,b,c可能的组合?
for a in range(0,1001):    for b in range(0,1001):        for c in range(0,1001):            if a**2 + b**2 == c**2 and a+b+c==1000:                print(a,b,c)

代码二

for a in range(0,1001):    for b in range(0,1001):        c = 1000 - a - b        if a**2 + b**2 == c**2 and a+b+c==1000:            print(a,b,c)

可以看出 相同的结果 不同的代码 时长不一样

评判程序优势的方法

  • 消耗计算机资源和执行效率(无法直观)
  • 计算算法执行的耗时(适当推荐,因为会受机器和执行环境的影响)
  • 时间复杂度(推荐)

时间复杂度:

  • 评判规则:量化算法执行的操作/执行步骤的数量
  • 最重要的项:时间复杂度表达式中最有意义的项
  • 大O记法:O(时间复杂度表达式中最有意义的项)

计算下列算法的时间复杂度

a=5b=6c=10for i in range(n):   for j in range(n):      x = i * i      y = j * j      z = i * jfor k in range(n):   w = a*k + 45   v = b*bd = 33

3+3n**2+2n+1

O(n**2)

常见的时间复杂度:

  • O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)

数据结构

  • 案例: 需要存储一些学生的学生信息(name,score),那么这些数据应该如何组织呢?查询某一个具体学生的时间复杂度是什么呢?(三种组织方式)
[    ['tom',100],['jay',99]]#O(n)
[    ('tom',100),('jay',99)]#O(n)
{    'tom':{
'score':100}, 'jay':{
'score':100},}#O(1)

如何测试代码性能?

  • timeit模块:该模块可以用来测试一段python代码的执行速度/时长。

  • Timer类:该类是timeit模块中专门用于测量python代码的执行速度/时长的。原型为:class timeit.Timer(stmt='pass',setup='pass')。

    • stmt参数:表示即将进行测试的代码块语句。

    • setup:运行代码块语句时所需要的设置。

    • timeit函数:timeit.Timer.timeit(number=100000),该函数返回代码块语句执行number次的

    • 计算运行平局耗时
    •  

      from timeit import Timerdef test01():    alist = []    for i in range(1000):        alist.append(i)def test02():    alist = []    for i in range(1000):        alist += [i]def test03():    alist = [i for i in range(1000)]def test04():    alist = list(range(1000))def test05():    alist = []    for i in range(1000):        alist.insert(i, i)if __name__ == '__main__':    timer = Timer(stmt='test01()', setup='from __main__ import test01')    print(timer.timeit(1000))    timer = Timer(stmt='test02()', setup='from __main__ import test02')    print(timer.timeit(1000))    timer = Timer(stmt='test03()', setup='from __main__ import test03')    print(timer.timeit(1000))    timer = Timer(stmt='test04()', setup='from __main__ import test04')    print(timer.timeit(1000))    timer = Timer(stmt='test05()', setup='from __main__ import test05')    print(timer.timeit(1000))########################0.12008433009207470.095425159609027930.0355146369787690260.0225343395261188850.178243830964033

先进后出的数据结构

栈顶,栈尾

Stack()创建一个空的新栈,他不需要参数,并返回一个空栈push(item)将一个新项添加到栈的顶部,它需要item做参数并不不返回任何内容pop()从栈中删除顶部的项,它不需要参数返回item,栈被修改peek()从栈返回顶部项,但不会删除isEmpty()测试栈是否为空,不需要参数,并返回布尔值size()返回栈中的item数量,不需要参数,并返回一个整数
class Stack():    def __init__(self):        self.items=[]    def push(self,item):        self.items.append(item)    def pop(self):        return self.items.pop()    def peek(self):        return self.items[-1]    def isEmpty(self):        return self.items==[]    def size(self):        return len(self.items)s=Stack()s.push('test1')s.push('test2')s.push('test3')print(s.pop())print(s.pop())print(s.peek())#返回栈的顶部print(s.isEmpty())#判断是否为空print(s.size())#返回栈的数量

网页回滚

s=Stack()def request(url):    s.push(url)def back():    print(s.pop())request('wwwbaidu1.com')request('www.baidu2.com')back()back()######www.baidu2.comwwwbaidu1.com

队列

先进先出

Queue()创建一个空的新队列,它不要参数

enqueue(item)将新项添加到队尾,它需要item作为参数

dequeue()从队首移除项,它不需要参数并返回item

isEmpry()查看队列是否为空 并返回布尔值

size()返回队列中的项书 并返回一个整数

class Queue():    def __init__(self):        self.items=[]    def enqueue(self,item):        self.items.insert(0,item)    def dequeue(self):        return  self.items.pop()    def isEmpty(self):        return self.items==[]#判断是否为空    def size(self):        return len(self.items)q=Queue()#创建一个空对列q.enquequ(1)q.enquequ(2)q.enquequ(3)print(q.dequeue())print(q.dequeue())

1

2

烫手的山芋

烫手山芋游戏介绍:6个孩子围城一个圈,排列顺序孩子们自己指定。第一个孩子手里有一个烫手的山芋,需要在计时器计时1秒后将山芋传递给下一个孩子,依次类推。 规则是,在计时器每计时7秒时,手里有山芋的孩子退出游戏。该游戏直到剩下一个孩子时结束,最后剩下的孩子获胜。请使用队列实现该游戏策略,排在第几个位置最终会获胜。

class Queue():    def __init__(self):        self.items=[]    def enqueue(self,item):        self.items.insert(0,item)    def dequeue(self):        return  self.items.pop()    def isEmpty(self):        return self.items==[]#判断是否为空    def size(self):        return len(self.items)q = Queue()alist = ['a', 'b', 'c', 'd', 'e', 'f']for i in alist:    q.enqueue(i)#把6个孩子加入队列while q.size() > 1:#循环队列大于一就跑    for i in range(6):#次数        kid = q.dequeue()#让对头的孩子退出队列        q.enqueue(kid)#在让加入队列    q.dequeue()#第6次之后 永久性退出循环#结束之后 把这个孩子取出print(q.dequeue())

双端队列

  • 同同列相比,有两个头部和尾部。可以在双端进行数据的插入和删除,提供了单数据结构中栈和队列的特性

 Deque()创建一个空的新deque,他不需要任何参数

addFront(item)将一个新项添加到deque的首部,他需要item参数

addRear(item)将一个新项添加到deque的尾部它需要iem参数

removeFront()从deque中删除首项,它不需要参数并返回item

removeRear()从deque中删除尾项,它不需要参数并返回item

isEmpty()测试deque是否为空,它不需要参数,并返回布尔值

size()返回deque中的项说,它不需要参数,并返回一个整数

class Deque():#创建一个空的deque    def __init__(self):        self.items = []    def addFont(self,item):#将一个新的项添加到deque首部        self.items.append(item)    def addRear(self,item):#将一个新的项添加dequ尾部        self.items.insert(0,item)    def removeFont(self):#删除首项        return self.items.pop()    def removeRear(self):#删除尾项        return self.items.pop(0)    def isEmpty(self):#测试是否为空        return self.items == []    def size(self):#返回deque中的项数        return len(self.items)def isHuiWen(word):    ex=True    q=Deque()    for ch in word:        q.addFont(ch)#双端队列从头部尾部添加都可以    while q.size() >1:        if q.removeFont() != q.removeRear():#头部取出 尾部取出             ex=False            break    return exprint(isHuiWen('toot'))

计算机存储理解

  • 指向:如果一个变量存储了某一块内存空间的地址,则表示该变量指向该块内存
  • 引用:如果一个变量存储了某一块内存空间的地址,则该变量可以成为该内存的一个引用

 

顺序表

  • 容器中存储的元素是有顺序的,顺序表的结构可以分为两种形式:单数据类型和多数据类型。
  • python中的列表和元组就属于多数据类型的顺序表

 相同类型属性的列表 存储结构

 不相同类型属性的列表 存储结构

链表

相对于顺序表,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理且进行扩充时不需要进行数据搬迁。

. is_empty():链表是否为空

. length():链表长度

. travel():遍历整个链表

. add(item):链表头部添加元素

. append(item):链表尾部添加元素

. insert(pos, item):指定位置添加元素

. remove(item):删除节点

. search(item):查找节点是否存在

add添加解

 travel遍历

class Node():    def __init__(self, item):        self.item = item        self.next = None  # 存储的链表中下一个节点的地址class Link():    def __init__(self):        # _head永远指向None或者第一个节点的地址        self._head = None    def add(self, item):        node = Node(item)        node.next = self._head#Node的self.next        self._head = node    def travel(self):        # cur存储的就是第一个节点的地址        cur = self._head        while cur:            print(cur.item)            cur = cur.nextlink=Link()link.add(1)link.add(2)link.add(3)link.travel()

回顾:

def is_Empty(self):#判断联表是否为空        return self._head == None    def size(self):        length = 0        if self._head == None:#如果head是空 直接返回            return length        #cur就是指向了第一个节点        cur = self._head        while cur:#不为空循环            length += 1            cur = cur.next#一直向下查找        return length

append

def append(self,item):        node = Node(item)        #如果链表为空则执行如下操作        if self._head == None:            self._head = node            return                cur = self._head#等于head头        pre = None        while cur:            pre = cur#上一个            cur = cur.next#下一个        pre.next = node#当前插入值            def search(self,item):        ex = False                cur = self._head        while cur:            if cur.item == item:#判断是否相等                ex = True                break            cur = cur.next#不断的往下查找        return ex

insert

def insert(self,pos,item):        node = Node(item)                if pos <= 0:#小于0add            self.add(item)            return        if pos >= self.size():#大于等于链表的长度插入尾部            self.append(item)            return                cur = self._head        pre = None                for i in range(0,pos):            pre = cur            cur = cur.next        pre.next = node        node.next = cur

 remove

def remove(self,item):        cur = self._head        pre = None        if cur.item == item:#删除第一个节点            self._head = cur.next            return        while cur:            pre = cur            cur = cur.next#做遍历            if cur.item == item:#意味着是我们想删除的节点                pre.next = cur.next#从c2划到c4                break

 总结:

class Node():    def __init__(self,item):        self.item = item        self.next = None #存储的链表中下一个节点的地址class Link():    def __init__(self):        #_head永远指向None或者第一个节点的地址        self._head = None          def add(self,item):        node = Node(item)        node.next = self._head        self._head = node    def travel(self):        #cur存储的就是第一个节点的地址        cur = self._head        while cur:            print(cur.item)            cur = cur.next    def is_Empty(self):        return self._head == None    def size(self):        length = 0        if self._head == None:            return length        #cur就是指向了第一个节点        cur = self._head        while cur:            length += 1            cur = cur.next        return length    def append(self,item):        node = Node(item)        #如果链表为空则执行如下操作        if self._head == None:            self._head = node            return                cur = self._head        pre = None        while cur:            pre = cur            cur = cur.next        pre.next = node            def search(self,item):        ex = False                cur = self._head        while cur:            if cur.item == item:                ex = True                break            cur = cur.next        return ex    def insert(self,pos,item):        node = Node(item)                if pos <= 0:            self.add(item)            return        if pos >= self.size():            self.append(item)            return                cur = self._head        pre = None                for i in range(0,pos):            pre = cur            cur = cur.next        pre.next = node        node.next = cur    def remove(self,item):        cur = self._head        pre = None        if cur.item == item:            self._head = cur.next            return        while cur:            pre = cur            cur = cur.next            if cur.item == item:                pre.next = cur.next                break

link = Link()

link.add(1)
link.add(2)
link.add(3)
link.append(4)
# link.insert(-2,'hello')
link.remove(3)
link.travel()

 

转载于:https://www.cnblogs.com/zaizai1573/p/10961473.html

你可能感兴趣的文章
GEOS/GDAL 交叉编译ARM64-linux版本
查看>>
Expression Blend实例中文教程(1) - 开篇
查看>>
Redis哨兵模式
查看>>
mongoengine
查看>>
正则表达式-包含A字符串且不包含B字符串
查看>>
MATLAB入门学习(整合)
查看>>
page=new page($total,$listrows,$query,$ord)之$query
查看>>
Android读取url图片保存及文件读取
查看>>
完整ASP.Net Excel导入
查看>>
判断CPU大小端示例代码
查看>>
ARTS打卡第13周
查看>>
循环队列的运用---求K阶斐波那契序列
查看>>
pta 编程题14 Huffman Codes
查看>>
初始化bootstrap treeview树节点
查看>>
python selenium向<sapn>标签中写入内容
查看>>
一次电脑上不去网的拯救之路
查看>>
JS常用坐标
查看>>
使用”结构化的思考方式“来编码和使用”流程化的思考方式“来编码,孰优孰劣?...
查看>>
C#调用斑马打印机打印条码标签(支持COM、LPT、USB、TCP连接方式和ZPL、EPL、CPCL指令)【转】...
查看>>
关于git的认证方式
查看>>