数据结构与算法-04栈
栈
栈(Stack)是一种线性数据结构,它的特点是只能在一端进行插入和删除操作,这一端被称为栈顶(Top),另一端被称为栈底(Bottom)。
栈的插入操作称为入栈(Push),删除操作称为出栈(Pop)。
栈的特点是后进先出(Last In First Out,LIFO),也就是最后入栈的元素最先出栈,而最先入栈的元素最后出栈。栈的应用非常广泛,例如函数调用、表达式求值、括号匹配等。
栈可以用数组或链表实现。用数组实现的栈称为顺序栈(Sequential Stack),用链表实现的栈称为链式栈(Linked Stack)。
顺序栈的实现比较简单,只需要一个数组和一个指针来表示栈即可。栈顶指针指向栈顶元素的位置,入栈操作将元素插入到栈顶指针指向的位置,栈顶指针加1;出栈操作将栈顶指针减1,返回栈顶元素。
链式栈的实现也比较简单,只需要一个链表和一个指针来表示栈即可。栈顶指针指向链表的头节点,入栈操作将元素插入到链表的头部,栈顶指针指向新的头节点;出栈操作将链表的头节点删除,栈顶指针指向新的头节点。
堆和栈一样吗?
栈(stack)一般编译器自动分配释放
堆(heap)一般由程序员分配释放,或程序结束后OS释放
栈的实现
class Stack(object):
def __init__(self):
self.__list = []
def push(self, item):
self.__list.append(item)
def pop(self):
return self.__list.pop()
def peek(self):
if self.__list:
return self.__list[-1]
else:
return None
def is_empoty(self):
return self.__list == []
def size(self):
return len(self.__list)
if __name__ == '__main__':
s = Stack()
a = "({[({{abc}})][{1}]})2([]){({[]})}[]"
m = {')':'(',']':'[','}':'{'}
for i in a:
if i in '([{':
s.push(i)
elif i in m:
if m[i] != s.pop():
print("fail")
break
else:
print("ok")
栈的应用
括号匹配
栈可以用来实现括号匹配的原因是,括号匹配的过程可以看作是将左括号入栈,遇到右括号时出栈,判断是否匹配。如果栈为空或者栈顶元素与当前右括号不匹配,则括号匹配不正确。
以下是一个简单的Python示例代码,演示了如何使用栈实现括号匹配:
def is_balanced(expression):
stack = Stack()
for char in expression:
if char in "([{":
stack.push(char)
elif char in ")]}":
if stack.is_empty():
return False
elif char == ")" and stack.peek() == "(":
stack.pop()
elif char == "]" and stack.peek() == "[":
stack.pop()
elif char == "}" and stack.peek() == "{":
stack.pop()
else:
return False
return stack.is_empty()
print(is_balanced("()"))
print(is_balanced("()[]{}"))
print(is_balanced("(]"))
print(is_balanced("([)]"))
print(is_balanced("{[]}"))
在这个示例代码中,首先定义了一个栈类Stack,包含了push、pop、is_empty和peek等方法。然后定义了一个is_balanced函数,用于判断括号匹配是否正确。在is_balanced函数中,遍历字符串中的每个字符,如果是左括号,则入栈;如果是右括号,则出栈并判断是否匹配。如果栈为空或者栈顶元素与当前右括号不匹配,则括号匹配不正确。最后判断栈是否为空,如果为空则括号匹配正确,否则不正确。
表达式求值
栈可以用来实现表达式求值,主要是因为表达式求值的过程可以看作是将操作数入栈,遇到操作符时出栈进行计算,将计算结果入栈。最终栈中只剩下一个元素,即为表达式的值。
以下是一个简单的Python示例代码,演示了如何使用栈实现表达式求值:
def evaluate(expression):
stack = Stack()
for char in expression:
if char.isdigit():
stack.push(int(char))
else:
operand2 = stack.pop()
operand1 = stack.pop()
if char == "+":
result = operand1 + operand2
elif char == "-":
result = operand1 - operand2
elif char == "*":
result = operand1 * operand2
elif char == "/":
result = operand1 / operand2
else:
raise ValueError("Invalid operator")
stack.push(result)
return stack.pop()
print(evaluate("3+4*5"))
print(evaluate("3*4+5"))
print(evaluate("4-2+3"))
print(evaluate("5/2"))
在这个示例代码中,首先定义了一个栈类Stack,包含了push、pop、is_empty和peek等方法。然后定义了一个evaluate函数,用于求解表达式的值。在evaluate函数中,遍历字符串中的每个字符,如果是数字,则入栈;如果是操作符,则出栈两个操作数进行计算,并将计算结果入栈。最终栈中只剩下一个元素,即为表达式的值。