[数据结构] 栈&队列
栈是限定只能在一端进行插入和删除操作的线性数据结构,具有后进先出(last in first out,LIFO
1 class Stack(object): 2 def __init__(self, limit = 20): 3 self.items = [] # 初始化为空列表 4 self.limit = limit # 指定栈的容量 5 6 7 '''判断栈是否为空,返回布尔值''' 8 def is_empty(self): 9 return self.items == [] 10 11 12 '''返回栈的大小''' 13 def size(self): 14 if self.items: 15 return len(self.items) 16 17 18 '''查看堆栈最上面的元素''' 19 def peek(self): 20 if self.items: 21 return self.items[len(self.items)-1] 22 23 24 '''入栈''' 25 def push(self,value): 26 if len(self.items) >= self.limit: 27 raise IndexError('index out of range!') 28 else: 29 self.items.append(value) 30 31 32 '''出栈''' 33 def pop(self): 34 if self.items: 35 self.items.pop() 36 else: 37 raise IndexError('can not pop item from an empty stack') 38 39 40 # 测试 41 if __name__ == "__main__": 42 # 初始化一个栈对象 43 my_stack = Stack() 44 my_stack.push('a') 45 my_stack.push('bc') 46 print(my_stack.size()) 47 print('---1---') 48 print(my_stack.peek()) 49 print('---2---') 50 my_stack.pop() 51 print(my_stack.peek()) 52 print('---3---') 53 print(my_stack.size()) 54 print('---4---') 55 my_stack.pop() 56 print(my_stack.is_empty())
tips. 实际应用中, 栈不需要我们自己定义,使用列表结构即可:
1. 进栈:append
2. 出栈:pop
3. 查看栈顶:list [-1] 直接取索引
(二). 栈的常见应用
1. 递归 -- 斐波那契数列
Fibonacci数列定义: f(0) = 0, f(1) = 1, f(n) = f(n-1) + f(n-2)
1 '''栈的应用 -- 1. 递归''' 2 # 实现斐波那契数列 3 4 def fibonacci_recursion(n): 5 if n < 2: 6 return n 7 else: 8 return fibonacci_recursion(n-1) + fibonacci_recursion(n-2) 9 10 # 测试 11 if __name__ == "__main__": 12 input = int(input('请输入数字:')) 13 if input < 0: 14 print('请输入正整数') 15 else: 16 print(fibonacci_recursion(input))
2. 括号匹配
思路:
(1). 只要碰到左括号, 进栈;
(2). 一旦碰到右括号, 先判断栈顶与当前字符是否是一对;
(3). 如果匹配, 就让栈顶的左括号出栈, 继续下一个字符;
(4). 如果不匹配, 直接return False;
1 def balance_parentheses(parentheses): 2 stack = Stack(len(parentheses)) # 初始化一个栈(数组) 3 balance = {'}':'{', ')':'(', ']':'[', '>':'<','》':'《'} # 字典:方便一一对应 4 for parenthesis in parentheses: 5 if parenthesis in balance.values(): # 如果是左括号 6 stack.append(parenthesis) 7 elif parenthesis in balance.keys(): 8 if balance[parenthesis] != stack.pop(): 9 return False 10 return True 11 12 # 测试 13 if __name__ == "__main__": 14 examples = ['((){})《','()()<>()(','','(({})))'] 15 for example in examples: 16 print(example+':'+ str(balance_parentheses(example)))
二. 队列
队列(queue)是一种具有先进先出特征的线性数据结构,元素的增加只能在一端进行,元素的删除只能在另一端进行。能够增加元素的队列一端称为队尾,可以删除元素的队列一端则称为队首.
队列符合先进先出[FIFO]的原则.
1 # python 实现队列 2 class Queue(object): 3 def __init__(self, size): 4 self.size = size 5 self.queue = [] 6 7 '''判断队列是否满了''' 8 def is_full(self): 9 if len(self.queue) == self.size: 10 return True 11 return False 12 13 '''判断队列是否为空''' 14 def is_empty(self): 15 return self.queue == [] 16 17 '''获取当前队列的长度''' 18 def get_length(self): 19 return len(self.queue) 20 21 '''入队''' 22 def enqueue(self,item): 23 if self.is_full(): 24 raise IndexError('full error') 25 self.queue.append(item) 26 27 '''出队''' 28 def dequeue(self): 29 if self.is_empty(): 30 raise IndexError('empty error') 31 first_ele = self.queue[0] 32 self.queue.remove(first_ele) 33 return first_ele 34 35 # 测试 36 if __name__ == '__main__' : 37 queueTest = Queue(5) 38 for i in range(5) : 39 queueTest.enqueue(i) 40 print(queueTest.is_full()) 41 print(queueTest.get_length()) 42 queueTest.dequeue() 43 print(queueTest.is_empty()) 44 print(queueTest.get_length())
(二). python内置的队列模块 -- queue
Python有自己的队列模块,我们只需要在使用时引入该模块就行.并且支持双向队列,优先级队列等;
1. 单向队列
from collections import Queue q = queue.Queue(10) # 不设置长度的话,默认为无限长度 print(q.maxsize) # 无括号 q.put(111) q.put('abc') q.put(['d','f']) print(q.get()) print(q.get()) print(q.get())
------------- 10 111 abc ['d', 'f']
2. 后进先出队列
from collections import LifoQueue q = queue.LifoQueue(10) # 不设置长度的话,默认为无限长度 print(q.maxsize) # 无括号 q.put(111) q.put('abc') q.put(['d','f']) print(q.get()) print(q.get()) print(q.get()) ------------ 10 ['d', 'f'] abc 111
3.
from collections import PriorityQueue q = queue.PriorityQueue() print(q.maxsize) # 无括号 q.put((1,'111')) q.put((2,'abc')) q.put((1,'def')) print(q.get()) print(q.get()) print(q.get()) ------------- 0 (1, '111') (1, 'def') (2, 'abc')
4.
from collections import deque q = queue.deque() q.append(111) q.append('abc') q.appendleft('def') print(q) print(q.pop()) print(q.popleft()) --------------- deque(['def', 111, 'abc']) abc def
🔚👋