Tree Traversals Again

一、题目

  1. Tree Traversals Again :

链接:https://pintia.cn/problem-sets/1340842164139356160/problems/1371047298293096448

思考:根据Push和Pop环节分别给出了该树的先序遍历和中序遍历,找到该树的后序遍历。
可以根据先序和中序建树,然后再对树进行后序遍历;
也可直接根据先序和中序确定后序。

  1. 是否同一棵二叉搜索树:

链接:https://pintia.cn/problem-sets/1340842164139356160/problems/1373201693693399040

思考:根据输入序列,建树,然后判断是否是同一棵树,建树过程与楼上类似.

  1. Root of AVL Tree :

链接:https://pintia.cn/problem-sets/1340842164139356160/problems/1373201693693399041

思考:仍然是建树,但是这次建树过程与楼上不同的是,需要建立平衡二叉树,因此插入节点时,一旦不平衡,就需要进行旋转,有LL LR RR RL四种情况。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
同时还需要动态跟进二叉树深度来判断现在该树是不是被破坏平衡了。
树建立好之后,输出根节点即可。
4. Complete Binary Search Tree :
链接:https://pintia.cn/problem-sets/1340842164139356160/problems/1373201693693399042
思考:需要同时考虑完全二叉树 二叉树搜索树的性质。
可以分为两种解法:
1.我觉得这种解法非常厉害,而且与网上很多人给出的解法不一样,更简洁明了。具体如下:
如果生成的树同时具备完全二叉树和二叉搜索树的性质,可以发现,如果对该树中序遍历,它是从小到大进行遍历的,对输入的数组进行排序,即可知中序遍历顺序。此时可以再想到完全二叉树的性质,左右子节点是2i,2i+1,对该二叉树进行中序遍历,即可将排序后的数组依次填入二叉树中。
2.第二种方法是先序遍历,先找根,根据完全二叉树和二叉搜索树的性质,知道总的节点个数,可以判断出根节点的位置,然后下放到左右子节点,继续找根节点的位置。因为是二叉搜索树,所以左边的一定都小于根节点,右边一定都大于,对于排序后的数组,可以很快锁定根节点的值。找根节点的思路如图:
在这里插入图片描述

二、解法

Tree Traversals Again
  • 先建树,随后后序遍历。思路为:若树节点空,则建立根节点root,父节点father。随后对于Push操作,先创立节点压入栈,若左子树为空,则插入到左子树,更新父节点,不然插入到右子树,更新父节点。对于Pop操作,栈顶节点弹出并将弹出的节点更新为父节点。建树结束后,采用后序遍历树的递归算法得到答案。
#定义节点和栈的类以及方法
class Stack:
  def __init__(self):
    self.items = []
  def Push(self,val):
    self.items.append(val)
  def Pop(self):
    return self.items.pop()
class Node:
  def __init__(self,val):
    self.val = val
    self.left = None
    self.right = None
res = []
def postOrderTravel(tree):
  if tree.left:
    postOrderTravel(tree.left)
  if tree.right:
    postOrderTravel(tree.right)
  res.append(tree.val)
number = int(input())
father = None
stack = Stack()
for i in range(2*number):
  text = input()
  if text == "Pop":
    father =stack.Pop()
  else:
    text,value = text.split()
    if not father:
      newNode = Node(value)
      root = newNode
      stack.Push(newNode)
    elif father.left == None:
      newNode = Node(value)
      stack.Push(newNode)
      father.left = newNode
    else:
      newNode = Node(value)
      stack.Push(newNode)
      father.right = newNode
    father = newNode
postOrderTravel(root)
print(" ".join(res))

在这里插入图片描述

  • 根据前序和中序直接找到后序遍历:前序的第一个必为根,将其确定为后序的最后一个,之后在中序中找到根,从而确定该树左右子树的个数,继续在左右子树中寻找左右子树的后序遍历,采用递归实现,结束递归条件为,序列为零直接return,若树的个数为一,则前中后遍历一样,记住该数的位置,return.
class Stack:
  def __init__(self):
    self.items = []
  def Push(self,val):
    self.items.append(val)
  def Pop(self):
    return self.items.pop()
def ascertainPost(pre,mid,post,n):
#pre mid post 分别为该树的前序 中序 后序的数组起始位置 n 为该树的个数 
  if n == 0:
    return 
  if n == 1:
    postOrder[post] = preOrder[pre]
    return
  # 前序遍历的第一个数必为该树的根
  root = preOrder[pre] 
  #则其为该树后序遍历的最后一个数
  postOrder[post+n-1]=root
  #根据根在中序遍历的位置 确定该树左右子树的数量
  for i in range(n):
    if inOrder[mid + i] == root:
      break
  leftChild = i 
  rightChild = n-i-1
  #分别堆左右子树继续递归 更新 pre mid post为左右子树的pre mid post
  ascertainPost(pre+1,mid,post,leftChild)
  ascertainPost(pre+leftChild+1,mid+leftChild+1,post+leftChild,rightChild)
  
number = int(input())
preOrder = []
inOrder = []
postOrder = [0]*number
stack = Stack()
for i in range(2*number):
  text = input()
  if text == "Pop":
    inOrder.append(stack.Pop())
  else:
    stack.Push(text.split()[1])
    preOrder.append(text.split()[1])
ascertainPost(0,0,0,number)
print(" ".join(postOrder))

在这里插入图片描述

是否同一棵二叉搜索树
class binarySearchTree:
  def __init__(self,val=None):
    self.value = val
    self.leftChild = None
    self.rightChild = None
   # 将节点依次插入到二叉搜索树中
  def insert(self,node):
    if self.value < node.value:
      if self.leftChild == None:
        self.leftChild = node
      else:
        return self.leftChild.insert(node)
    else:
      if self.rightChild == None:
        self.rightChild = node
      else:
        return self.rightChild.insert(node)
def buildTree(alist):
  root=binarySearchTree(alist[0])
  for i in alist[1:]:
    node = binarySearchTree(i)
    root.insert(node)
  return root
# 判断两棵树是否相等 用递归的方法
def isSame(root1,root2):
  if root1 == root2 == None:
    return True
  if root1 and root2 :
    if root1.value == root2.value:
      return isSame(root1.leftChild,root2.leftChild) and isSame(root1.rightChild,root2.rightChild)
  else:
    return False

text = input()
while text != "0":
  N,L = text.split()
  initList = list(map(int,input().split()))
  initTree = buildTree(initList)
  for _ in range(int(L)):
    comparList = list(map(int,input().split()))
    comparTree = buildTree(comparList)
    if isSame(initTree,comparTree):
      print("Yes")
    else:
      print("No")
  text = input()

在这里插入图片描述

Root of AVL Tree
class node:
  def __init__(self,value = None):
    self.value = value
    self.leftChild = None
    self.rightChild = None 

def buildTree():
  no = list(map(int,input().split()))
  root = node(no[0])
  for num in no[1:]:
    root = insert(root,num)
  return root

def height(root):
  if root  == None:
    return 0
  else:
    return max(height(root.leftChild),height(root.rightChild))+1

def LLrotation(root):
  br = root.leftChild.rightChild
  a = root
  root = root.leftChild
  
  a.leftChild = br
  root.rightChild =  a 
  return root

def LRrotation(root):
  c =  root.leftChild.rightChild
  cr = root.leftChild.rightChild.rightChild
  cl = root.leftChild.rightChild.leftChild
  b = root.leftChild
  a = root

  root = c
  root.leftChild = b
  root.rightChild = a
  b.rightChild = cl
  a.leftChild = cr
  return root

def RRrotation(root):
  b = root.rightChild
  bl = root.rightChild.leftChild
  a = root

  root = b
  b.leftChild = a
  a.rightChild = bl
  return root

def RLrotation(root):
  c = root.rightChild.leftChild
  b = root.rightChild
  a = root
  cl = root.rightChild.leftChild.leftChild
  cr = root.rightChild.leftChild.rightChild

  root = c
  c.leftChild = a
  c.rightChild = b
  a.rightChild = cl
  b.leftChild =cr
  return root

def insert(root,newNode):
  if root == None:
    root = node(newNode)
  else:
    if newNode < root.value:
      root.leftChild = insert(root.leftChild,newNode)
      if abs(height(root.leftChild)-height(root.rightChild) == 2):
        if newNode < root.leftChild.value:
          root = LLrotation(root)
        else:
          root = LRrotation(root)
    else:
      root.rightChild = insert(root.rightChild,newNode)
      if abs(height(root.rightChild) - height(root.leftChild) == 2):
        if newNode > root.rightChild.value:
          root = RRrotation(root)
        else:
          root = RLrotation(root)
  return root

number = int(input())
root = buildTree()
print(root.value)


在这里插入图片描述

Complete Binary Search Tree
def inOrder(root):
  if root > number:
    return 
  inOrder(root*2)
  global index
  treeArray[root] = sortList[index]
  index += 1
  inOrder(root*2+1)

number = int(input())
treeArray = [0]*(number+1)
index = 0
sortList = list(map(int,input().split()))
sortList.sort()

inOrder(1)

print(" ".join(list(map(str,treeArray[1:]))))

在这里插入图片描述

import math
# 找根节点的位置
def getLeft(n):
  H = int(math.log2(n+1))
  X = n+1-2**H
  L = (2**(H-1)-1)+min(X,2**(H-1)) 
  return L
# 先序遍历根节点 并填入值
def solve(left,right,root):
  n = right-left+1 
  if n == 0:
    return 
  leftIndex = getLeft(n)
  treeArray[root] = sortList[left+leftIndex]
  solve(left,left+leftIndex-1,root*2)
  solve(left+leftIndex+1,right,root*2+1)

number = int(input())
treeArray = [0]*(number+1)
sortList = list(map(int,input().split()))
sortList.sort()
solve(0,number-1,1)

print(" ".join(list(map(str,treeArray[1:]))))

在这里插入图片描述

总结

对于二叉树的结构,节点的插入,二叉树的平衡转换操作,二叉树的深度,有了更清晰的认识。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值