python 数据结构简介,,栈(stack)定义


栈(stack)

定义:

  数据集合,只能在一端(首尾)进行删除和插入的列表。

特点:

  后进先出(LIFO)

典型作用:

  括号匹配:左括号进栈,右括号跟左括号对应则出栈,例如:(({{[]}}))匹配

队列(queue)

定义:

  线性表,只能在表的一端进行插入,在另一端进行删除操作。

特点:

  先进先出(FIFO)

栈和队列的比较:

  1遍历速度方向:栈只能从头部取数据,如果要取第一个数据则需要遍历整个栈,队列则可以从头部或尾部遍历,但不能同时遍历

  2遍历空间:栈遍历时需要另行开辟临时空间,保持数据在遍历前的一致性,队列则是基于地址指针进行遍历,无需临时空间则可保持一致性

  3两者均是线性表,即数据元素之间的关系相同,但是由因为对插入和删除的限定条件,则成为有限定的线性表。

下面时对队列和栈的一个对比应用:迷宫(maze)

  假设有这么一个迷宫地图:

  技术分享

  嘉定灰色为0,白色为1,用一个列表来表示为:

maze = [    [1,1,1,1,1,1,1,1,1,1],    [1,0,0,1,0,0,0,1,0,1],    [1,0,0,1,0,0,0,1,0,1],    [1,0,0,0,0,1,1,0,0,1],    [1,0,1,1,1,0,0,0,0,1],    [1,0,0,0,1,0,0,0,0,1],    [1,0,1,0,0,0,1,0,0,1],    [1,0,1,1,1,0,1,1,0,1],    [1,1,0,0,0,0,0,0,0,1],    [1,1,1,1,1,1,1,1,1,1]]

  首先使用栈的方法,指定一个方向优先级,比如下,右,左,上的顺序,向栈中不断push数据,直到到达终点的位置为止。

  定义四个方向  

dirs = [lambda x, y: (x + 1, y),        lambda x, y: (x, y + 1),        lambda x, y: (x - 1, y),        lambda x, y: (x, y - 1),        ]

  主程序:

def map_path(x1,y1,x2,y2):    stack=[]    stack.append((x1,y1))#添加起始点    while len(stack)> 0:    #如果栈中有数据的话        curNode=stack[-1]   #取最外面一个栈值        if curNode[0]==x2 and curNode[1]==y2:   #如果到达终点            print(‘found path‘)            for p in stack:                print(p)            return True        for dir in dirs:    #循环四个方向,注意优先级            nextNode=dir(curNode[0],curNode[1]) #定义下一个点            if maze[nextNode[0]][nextNode[1]]==0:   #如果下一个点可以走通                stack.append(nextNode)  #添加进栈中                maze[nextNode[0]][nextNode[1]] = -1 #改变值使不重复添加                break        else:            stack.pop()    print(‘found failed‘)    return Falsemap_path(1,1,8,8)

  最后的结果输出为:

技术分享
found path(1, 1)(2, 1)(3, 1)(4, 1)(5, 1)(5, 2)(5, 3)(6, 3)(6, 4)(6, 5)(7, 5)(8, 5)(8, 6)(8, 7)(8, 8)
输出结果

  在这里注意到如果更改dir的顺序,即可调整走出迷宫的优先级,路径就会不一样,我在这里只能根据相对位置(左下方)进行一个寻位的排序。如果有大神知道如何在此基础上能找到绝对的最有路径,还望赐教。

讲完了栈,下面使用队列来实现同样的功能:

  

def print_p(path):    curNode = path[-1] #包含了所有的路径    realpath=[] #只记录走到终点的真实路径    while curNode[2]!=-1:   #只要不是第一个        realpath.append(curNode[0:2])           curNode=path[curNode[2]]    #继续找下一个    realpath.append(curNode[0:2])   #拿到最后一个源头    realpath.reverse()    print(realpath)def map_path(x1,y1,x2,y2):    queue = deque()    path=[] #创建列表记录路径    queue.append((x1,y1,-1))    #-1是设置用于路径来源搜搜索    while len(queue)>0:        curNode=queue.popleft()        path.append(curNode)        if curNode[0]==x2 and curNode[1]==y2:            print_p(path)            return True        for dir in dirs:            nextNode = dir(curNode[0],curNode[1])            if maze[nextNode[0]][nextNode[1]]==0:   #如果找到有空                queue.append((*nextNode,len(path)-1))   #len用于记录产生这个新node的来源                maze[nextNode[0]][nextNode[1]] = -1 #如果没有空    print(‘found failed‘)    return Falsemap_path(1,1,8,8)

  最后结果为:

[(1, 1), (2, 1), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (6, 3), (6, 4), (6, 5), (7, 5), (8, 5), (8, 6), (8, 7), (8, 8)]

  根据两种不同的方法实现迷宫的解答凸显了两种查找方式:深度查找和广度查找,栈体现的就是深度,一直到底然后再返回查询,队列则体现的是广度查找,把每个点的可能性都列出来,然后找到最后一个可以到达重点的,再通过反向溯源找到路径。

  

  

python 数据结构简介

评论关闭