目录标题
线性表的两种存储结构各有哪些优缺点?
-
顺序存储结构(数组):
- 优点:
- 存储空间利用率高。
- 可以通过索引快速访问任意位置的元素。
- 插入和删除操作(在非尾部)可能需要移动大量元素。
- 缺点:
- 需要预先分配固定大小的存储空间。
- 插入和删除操作可能效率较低,尤其是当元素不在数组尾部时。
- 优点:
-
链式存储结构(链表):
- 优点:
- 动态分配存储空间,可以根据需要增加或减少。
- 插入和删除操作相对简单,只需修改指针。
- 缺点:
- 每个节点需要额外的存储空间来存放指针。
- 访问元素需要从头节点开始遍历,不能直接访问。
- 优点:
使用栈结构实现括号匹配问题
- 核心思路:
- 主要通过不断将左括号入栈,若匹配,则,对应左括号出栈,若不匹配,则失败,最终栈空表示,全部匹配成功。
- 每个右圆括号与最近遇到的尚未匹配的左圆括号匹配;
- 每个右方括号与最近遇到的尚未匹配的左方括号匹配;
- 每个右花括号与最近遇到的尚未匹配的左花括号匹配;
- 示意图

- 代码实现
python
class Node:
"""
定义链栈结点类型
"""
def __init__(self, data):
# 结点的数据域
self.data = data
# 结点的指针域
self.next = None
class LinkedStack:
"""
链栈的定义
"""
def __init__(self):
"""
初始化
"""
# 栈的头结点指针
self.top = Node(None)
def isEmpty(self):
"""
判断为空
:return: true or false
"""
return self.top.next is None
def push(self, data):
"""
入栈
:param data: 入栈元素
:return:
"""
newNode = Node(data)
# 新结点的next指向栈顶指针
newNode.next = self.top.next
# 将栈顶指针指向新结点
self.top.next = newNode
def pop(self):
"""
出栈
:return: 出栈元素值
"""
if self.isEmpty():
raise IndexError('栈为空')
# 存储栈顶元素
node = self.top.next
# 指向栈顶的下一个元素
self.top.next = self.top.next.next
# 返回栈顶元素
return node
def peak(self):
"""
获取栈顶
:return: 返回栈顶元素
"""
if self.isEmpty():
raise IndexError('栈为空')
else:
return self.top.next.data
# 括号匹配问题
def match(self, char1, char2):
"""
判断是否匹配
:param char1: 需要匹配第一个字符
:param char2: 需要匹配第二个字符
:return:
"""
if char1 == '(' and char2 == ')':
return True
elif char1 == '[' and char2 == ']':
return True
elif char1 == '{' and char2 == '}':
return True
else:
return False
def brackedMatch(self, str):
"""
括号匹配
:param str: 表达式
:return:
括号匹配成功,返回true
括号匹配失败,返回false
"""
stack = LinkedStack()
arr = list(str)
for i in range(len(arr)):
# 如果字符为'('、'['、'{',将其入栈
if arr[i] == '(' or arr[i] == '[' or arr[i] == '{':
stack.push(arr[i])
elif arr[i] == ')' or arr[i] == ']' or arr[i] == '}':
# 判断是否空栈
if stack.isEmpty():
print(f'右括号{arr[i]}多余')
return False
else:
char = stack.peak()
if stack.match(char, arr[i]):
stack.pop()
else:
print(f'对应的左括号{char}与右括号{arr[i]}不匹配')
return False
if stack.isEmpty():
print('当前字符串的括号匹配')
return True
else:
print(f'左括号{stack.peak().data}多余')
return False
if __name__ == '__main__':
# print('PyCharm')
# 13.括号匹配问题
linkedStack = LinkedStack()
expStr = '({[((1)+2)+(3+4)]+(5+(6))})'
linkedStack.brackedMatch(expStr)
使用队列实现杨辉三角
-
核心思想
- 将每一行的数据元素入队,
- 下一行从第二个元素开始,由上一行的出队元素和队首两个元素相加而得;
- 循环往复,获得杨辉三角
-
杨辉三角特点
- 每一行的第一个数字与最后一个数字均为1;
- 其他位置上的数字是上一行中与之相邻的两个数字之和。
-
示意图
-
代码实现
python
class Node:
"""
定义链式队列结点
"""
def __init__(self, data):
# 数据域
self.data = data
# 指针域
self.next = None
class LinkedQueue:
"""
链式队列定义
"""
def __init__(self):
"""
链式队列初始化
"""
# 队首结点指向None
self.front = Node(None)
# 队尾指针指向队首
self.rear = self.front
def isEmpty(self):
"""
判断是否为空
:return: true or false
"""
return self.front == self.rear
def enter(self, data):
"""
入队
:param data: 入队元素值
"""
# 创建新结点
newNode = Node(data)
self.rear.next = newNode
self.rear = newNode
def delete(self):
"""
出队
:return: 出队值
"""
# 队列为空
if self.isEmpty():
raise IndexError('队列为空')
else:
node = self.front.next
# 队首结点的next指向队首结点的后继结点
self.front.next = node.next
# 返回出队结点
return node
def peak(self):
"""
获取队首元素
:return: 队首元素
"""
# 队列为空
if self.isEmpty():
raise IndexError('队列为空')
else:
# 返回队首元素
return self.front.next.data
def pascalTriangle(self):
"""
杨辉三角的应用
:return:
"""
# 第1行数字入队
self.enter(1)
line = eval(input('请输入行数:'))
# 产生第n行数字,并入队,同时打印出
for n in range(2, line + 2):
# 打印空格
for i in range(line - n + 1):
print('', end='')
# 步骤1:第n行第一个数字入队
self.enter(1)
# 步骤2:输出第n-1行数字,同时产生第n行中间的第n-2个数字并将其入队
for i in range(1, n-1):
# 步骤2-1:打印第n-1行数字
temp = self.delete().data
print(temp, end=" ")
# 步骤2-2:利用队列中第n-1行数字产生第n行数字
num = self.peak()
num = num + temp
self.enter(num)
# 步骤3:打印第n-1行的最后一个数字
num = self.delete().data
print(num, end=' ')
# 步骤4:第n行的最后1个数字入队
self.enter(1)
print()
if __name__ == '__main__':
print('PyCharm')
# 14.杨辉三角
linkedQueue = LinkedQueue()
linkedQueue.pascalTriangle()
结合栈和队列实现回文判断
- 核心思想
- 通过将字符依次插入栈和队列,再依次对栈顶元素和队首元素的字符进行比较,实现回文判断。
- 代码实现
python
if __name__ == '__main__':
print('PyCharm')
# 15. 回文
chars = 'abcdefggfedcba'
linkedStack = LinkedStack()
linkedQueue = LinkedQueue()
is_palindrome = True
for char in chars:
linkedStack.push(char)
linkedQueue.enter(char)
while linkedStack.isEmpty() is False:
print('进入循环')
if linkedStack.pop().data != linkedQueue.delete().data:
is_palindrome = False
break
result = '字符是回文' if is_palindrome else '字符不是回文'
print(f"字符串 '{chars}'\t{result}")