1.中綴表達式的計算
給定一個合法的表達式字符串,其中只包含非負整數、加法、減法以及乘法符號(不會有括號),例如7+3*4*5+2+4-3-1,請寫程序計算該表達式的結果並輸出。
思路:step1:建立數字棧和操作符棧 stacknum stackop
step2:遍歷表達式::假如是數字–>壓棧到數字棧
假如是字符–>if 遍歷到的運算符優先級高或者操作符棧爲空:直接將操作符壓棧。
else 遍歷到運算符優先級低於操作符棧的最後一個操作符:取出操作符棧最後一個操作與數字棧的後兩個數字進行計算。將計算之後的數字壓棧,將目前遍歷到的操作符壓棧
step3:如果操作符棧不爲空,循環:取出操作符棧最後一個操作與數字棧的後兩個數字進行計算。將計算之後的數字壓棧。數字棧最終的字符即爲所求。
s=input("")
stacknum=[]
stackop=[]
for i in range(len(s)):
if s[i] in ['+', '-', '*']:
if not stackop:
stackop.append(s[i])
elif s[i] in ['+', '-'] and stackop[-1] in['*']:
num1 = stacknum.pop()
num2 = stacknum.pop()
op = stackop.pop()
if op == '+':
term = num1 + num2
elif op == '-':
term = num2 - num1
else:
term = num1 * num2
stacknum.append(term)
stackop.append(s[i])
else:
stackop.append(s[i])
else:
stacknum.append(int(s[i]))
print(stacknum)
print(stackop)
while len(stackop)>=1:
num1=stacknum.pop()
num2=stacknum.pop()
op = stackop.pop()
if op=='+':
term = num1+num2
elif op=='-':
term = num2-num1
else:
term = num1*num2
stacknum.append(term)
print(stacknum[0])
2.兩個棧實現隊列(劍指offer第9題)
思路:插入數據:直接插入到第一個棧; 取出數據:如果第二個棧不爲空,則直接彈出最外部的元素;否則將1棧元素依次取出並放入2棧。
stack1=[]
stack2=[]
N=int(input(""))
lis=[None]*N
for i in range(N):
lis[i]=[n for n in input().split(" ")]
for i in range(N):
if len(lis[i])==2:
stack1.append(lis[i][1])
elif len(lis[i])==1:
if lis[i][0]=='peek':
if len(stack2)!=0:
print(stack2[-1])
else:
for i in range(len(stack1)):
t=stack1.pop()
stack2.append(t)
print(stack2[-1])
elif lis[i][0]=='poll':
if len(stack2)!=0:
stack2.pop()
else:
for i in range(len(stack1)):
t = stack1.pop()
stack2.append(t)
stack2.pop()
3.二叉樹遍歷(先序、中序、後序、寬度優先遍歷)的迭代實現和遞歸實現
定義二叉樹:
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
先序遍歷(遞歸):
def preorder(root):
if not root:
return
print(root.val)
preorder(root.left)
preorder(root.right)
先序遍歷迭代:
def preorder(root):
stack = [root]
while stack:
s=stack.pop()
if s:
print(s.val)
stack.append(s.right)
stack.append(s.left)
層次遍歷:
def BFS(root):
queue = [root]
while queue:
n=len(queue)
for i in range(n):
q=queue.pop(0)
if q:
print(q.val)
queue.append(q.left if q.left else None)
queue.append(q.right if q.right else None)
4.二叉樹的鏡像(劍指offer27題)
請完成一個函數,輸入一個二叉樹,該函數輸出它的鏡像。
思路:遞歸地交換每棵樹的子節點。
def mirror(root):
if not root:
return
root.lchild,root.rchild=root.rchild,root.lchild
mirror(root.lchild)
mirror(root.rchild)
5.輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。(劍指offer第7題)
思路:二叉樹的先序遍歷遍歷中,第一個數字總是樹的根節點的值。但在中序遍歷中,根節點的值在序列的中間。
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
if len(preorder)<1 or len(inorder)<1:
return None
root=TreeNode(preorder[0])
for i in range(len(inorder)):
if inorder[i]==preorder[0]:
flag=i
break
root.left=buildTree(preorder[1:flag+1], inorder[:flag])
root.right=buildTree(preorder[flag+1:], inorder[flag+1:])
return root
6.對稱的二叉樹(劍指offer28題)
請實現一個函數,用來判斷一棵二叉樹是不是對稱的。如果一棵二叉樹和它的鏡像一樣,那麼它是對稱的。
思路:都遍歷完,即相同; 一個遍歷完一個沒完或者左右子樹值不相同則不是對稱的;其餘情況需要保證根的左子樹的右子樹 需要和 根的右子樹的左子樹一樣, 根的左子樹的左子樹 需要和 根的右子樹的右子樹一樣。
#遞歸判斷左右子樹是否符合
def func(L, R):
if L==None and R==None:
return True
if (L==None and R!=None) or (L!=None and R==None):
return False
if L.val != R.val:
return False
#判斷
return func(L.left, R.right) and func(L.right, R.left)
def isSymmetric(root):
#根不爲空 則繼續判斷左右字樹
return func(root.left, root.right) if root else True
7.從上到下打印二叉樹(劍指offer32題)
從上到下打印出二叉樹的每個節點,同一層的節點按照從左到右的順序打印。
思路:利用隊列完成層次遍歷
def levelOrder(root):
queue=[]
lis=[]
if root:
queue.append(root)
else:
return lis
while(queue):
r = queue.pop(0)
lis.append(r.val)
if r.left:
queue.append(r.left)
if r.right:
queue.append(r.right)
return lis
8.二叉搜索樹的第k大節點(劍指offer54題)
給定一棵二叉搜索樹,請找出其中第k大的節點。
思路:中序遍歷二叉搜索樹可以得到順序排列的數值。
#中序遍歷函數 返回一個順序排列的列表。
def inord(root1):
lis=[]
le=[]
ri=[]
if root1.left!=None:
le=inord(root1.left)
lis.append(root1.val)
if root1.right!=None:
ri=inord(root1.right)
return le+lis+ri
#主函數 返回列表的第 (長度-k項)
def kthLargest(root, k) :
lis=inord(root)
leng = len(lis)
return lis[leng-k]
9.二叉樹的深度(劍指offer55題)
輸入一棵二叉樹的根節點,求該樹的深度。從根節點到葉節點依次經過的節點(含根、葉節點)形成樹的一條路徑,最長路徑的長度爲樹的深度。
思路:根節點的深度等於 左右子樹較大深度的那個加1。
def maxDepth(root):
if root==None:
return 0
#葉子節點返回1
if root.left==None and root.right==None:
return 1
sum = 0
#深度 等於左右子樹深度的較大值加1
sum+=1
sum+=max(maxDepth(root.left), maxDepth(root.right))
return sum