什么是数据结构?
简单来说,数据结构就是设计数据以何种方式组织并并存储在计算机中
比如 :列表,集合与字典都是一种数据结构
N.Wirth:“程序=数据结构+算法”
1、列表
在其他编程语言中称为“数组”,是一种基本的数据结构类型,这里就不过多阐述了,具体的可以参照Python基础查看用法实例
2、栈
栈是一个数据集合,可以理解为只能在一段进行插入或者删除操作的列表
特点:后进先出
进栈(压栈):push
出栈:pop
取栈顶:gettop
所有元素操作从栈顶开始
不需要自己定义,使用列表结构即可
栈的应用--括号匹配问题
# 括号匹配问题 def check_char(s): stack = [] for char in s: if char in {'(', '[', '{'}: stack.append(char) elif char == ')': if len(stack) > 0 and stack[-1] == '(': stack.pop() else: return False elif char == ']': if len(stack) > 0 and stack[-1] == '[': stack.pop() else: return False elif char == '}': if len(stack) > 0 and stack[-1] == '{': stack.pop() else: return False if len(stack) == 0: return True else: return False check_char('([{}])')
栈的迷宫游戏解决
# 栈的思路解决迷宫问题 maze = [ [1, 0, 1, 0], [0, 0, 0, 1], [1, 0, 0, 1], [1, 1, 0, 0] ] # 定义的四个方向 dirs = [lambda x, y: (x + 1, y), lambda x, y: (x - 1, y), lambda x, y: (x, y - 1), lambda x, y: (x, y + 1)] def mpath(x1, y1, x2, y2): stack = [] stack.append((x1, y1)) while len(stack) > 0: # 栈不空时循环 curNode = stack[-1] # 查看栈顶元素 if curNode[0] == x2 and curNode[1] == y2: # 到达终点 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: # 四个方向都没有找到 maze[curNode[0]][curNode[1]] = -1 # 标记死路 stack.pop() # 回溯 print('None') return False
栈的思路,深度优先,回溯
队列的思路,广度优先
3、队列
队列是一个数据集合,仅允许在列表的一端进行插入,另一端进行删除
进行插入的一端称为队尾(rear),插入动作称为进队或者入队
进行删除的一端称为队头,删除的动作称为出队
队列的性质:先进先出
双向队列:队列的两端都允许进行进队和出队操作
队列不可以用简单的列表实现
使用方法:from collections import deque
创建队列:queue = dque(li)
进队:append
出队:popleft
双向队列队首进队:appendleft
双向队列队尾进队:pop
队列的实现原理
初步设想:列表 + 两个下标指针
创建一个列表和两个变量,front变量指向队首,rear变量指向队尾,初识时front和rear都为0
进队操作:元素写到li[rear]的位置rear自增1
出队操作:返回li[front]元素front自减1
改进方案:将列表首位逻辑上连接起来
4、链表
每个元素都是一个对象,每个对象称为一个节点,包含有数据域key和指向下一个节点的指针next。通过各个节点之间的相互连接,最终串联成一个链表
class Node(): def __init__(self, item=None): self.item = item self.next = None self.prior = None
链表节点的插入和删除
链表插入和删除的时间复杂度都是o(1)
python中的集合与字典
集合与字典查找在不发生哈希冲突时的时间复杂度是o(1)
哈希表查找
哈希表又称为散列表,是一种线性表的存储结构,通过把每个对象的关键字k作为自变量,通过一个哈希函数h(k),将k映射到下标h(k)处,并将该对象存储在这个位置
哈希函数种类有很多,
哈希冲突:由于哈希表的下标范围是有限的,二元素关键字的值是接近无限的,因此可能会出现h(1) = 1, h(20008) = 1这种情况。此时两个元素映射到同一个下标处,造成哈希冲突
解决哈希冲突
1、拉链法:将所有冲突的元素用链表连接
2、开放寻址法:通过哈希冲突函数得到新的地址