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