编程笔试题※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()

最长的有效括号
给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。

ans = 0
for i in range(len(s)):
    # 入栈条件
    if not stack or s[i] == '(' or s[stack[-1]] == ')':
        stack.append(i)     # 下标入栈
    else:
    # 计算结果
        stack.pop()
        ans = max(ans, i - (stack[-1] if stack else -1))
return ans

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

10.之字形打印二叉树
思路: 一个奇数层栈, 一个偶数层栈。
一个代表当前树层次的值。
值为奇数:打印奇数层,偶数层压榨,先右节点 再左节点
值为偶数:打印偶数层,奇数层压榨,先左节点 再又节点

#代码包括 构建树结构 和 用例
class TreeNode:
    def __init__(self, value):
        self.left=None
        self.right=None
        self.value=value
def func(root):
    if root==None:
        return False
    oddstack=[]
    evenstack=[]
    level=1
    oddstack.append(root)
    while(oddstack or evenstack):
        if level%2==1:
            while(oddstack):
                temp = oddstack.pop()
                if temp:
                    print(temp.value)
                    evenstack.append(temp.right if temp.right else None)
                    evenstack.append(temp.left if temp.left else None)
        else:
            while (evenstack):
                temp = evenstack.pop()
                if temp:
                    print(temp.value)
                    oddstack.append(temp.left if temp.left else None)
                    oddstack.append(temp.right if temp.right else None)
        level+=1
root = TreeNode(1)
l_1 = TreeNode(2)
l_2 = TreeNode(3)
root.left = l_1
root.right = l_2
l_2_1=TreeNode(4)
l_2_2=TreeNode(5)
l_2_3=TreeNode(6)
l_2_4=TreeNode(7)
l_1.left = l_2_1
l_1.right = l_2_2
func(root)

11.二叉树中和为某一值的路径
输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。
思路:深度优先搜索,回溯

res, path = [], []
def recur(root, tar):
    if not root: return
    path.append(root.val)
    tar -= root.val
    if tar == 0 and not root.left and not root.right:
        res.append(list(path))
    recur(root.left, tar)
    recur(root.right, tar)
    path.pop()
recur(root, sum)
return res
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值