編程筆試題※python實現※棧/隊列/樹類

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章