左神算法、牛客网算法-初级5(python实现)

实现二叉树的先序、 中序、 后序遍历,

包括递归方式和非递归方式

class TreeNode():
    def __init__(self,value):
        self.value = value
        self.right = None
        self.left = None

递归模式

def preOrderRecur(root):
    if not root:
        return 
    print(root.value, end=" ")
    preOrderRecur(root.left)
    preOrderRecur(root.right)
def inOrderRecur(root):
    if not root:
        return 
    preOrderRecur(root.left)
    print(root.value, end=" ")
    preOrderRecur(root.right)
def posOrderRecur(root):
    if not root:
        return 
    preOrderRecur(root.left)
    print(root.value, end=" ")
    preOrderRecur(root.right)

非递归 使用stack

前序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WKu26FxM-1588470251314)(attachment:image.png)]
中序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PebuVpmY-1588470251320)(attachment:image.png)]

def preOrderRecur(root):
    # 前序  中左右
    if not root:
        return 
    stack = [root]
    while stack:
        tmp = stack.pop()
        print(tmp.value)
        if tmp.right:
            stack.append(tmp.right)
        if tmp.left:
            stack.append(tmp.left)
            
def inOrderRecur(root):
    # 先压入所有左边界,再弹出最左边的节点,  左中右
    if not root:
        return 
    stack = []
    while stack or root:
        if root:
            stack.append(root)
            root = root.left
        else:
            root = stack.pop()
            print(root.value, end=" ")
            root = root.right
def posOrderRecur(root):
    # 先实现 中右左  将结果存入栈中  再依次弹出,即为后序  左右中
    if not root:
        return 
    res = []
    stack = [root]
    while stack:
        tmp = stack.pop()
        res.append(tmp.value)
        if tmp.left:
            stack.append(tmp.left)
        if tmp.right:
            stack.append(tmp.right)
    while res:
        print(res.pop())

在二叉树中找到一个节点的后继节点

【题目】 现在有一种新的二叉树节点类型如下:

public class Node { public int value; public Node left;

public Node right; public Node parent;

public Node(int data) { this.value = data; }

}

该结构比普通二叉树节点结构多了一个指向父节点的parent指针。 假
设有一 棵Node类型的节点组成的二叉树, 树中每个节点的parent指针
都正确地指向 自己的父节点, 头节点的parent指向null。 只给一个在
二叉树中的某个节点 node, 请实现返回node的后继节点的函数。 在二
叉树的中序遍历的序列中, node的下一个节点叫作node的后继节点。

# 从节点拿到跟节点 中序遍历整个树,拿到该节点的下个个节点的值即可
def get_next_Node(node):
    if not node:
        return
    tmp = node
    while tmp.parent:
        tmp = tmp.parent
    # tmp 即为根节点
    res = []
    stack = []
    while stack or tmp:
        if tmp:
            stack.append(tmp)
            tmp = tmp.left
        else:
            tmp = stack.pop()
            res.append(tmp)
            tmp = tmp.right
    for i in range(len(res)-1):
        if res[i] == node:
            return res[i+1]
    return res[-1]

中序遍历某个节点的下个值就是他的后继及节点

如果该节点有右子节点, 那么后继是其右子节点的子树中最左端的节点
如果该节点没有右子节点, 那么后继是离它最近的祖先, 该节点在这个祖先的左子树内.

如果某个节点有右节点,则右节点的最左叶节点即为他的后继节点(左中右)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yZM9Jdj4-1588470251326)(attachment:image.png)]
如果某个节点没有右节点,那么依次向上找到当前节点是左节点的父节点,这个父节点就是某个节点的后继节点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EQ2hkksb-1588470251331)(attachment:image.png)]

介绍二叉树的序列化和反序列化

前序遍历
中序遍历
后序遍历
按层序列化

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Codec:

    def serialize(self, root: TreeNode) -> str:
        """Encodes a tree to a single string.
        """
        if not root:
            return "#!"
        res = str(root.val) + "!"
        res += self.serialize(root.left)
        res += self.serialize(root.right)
        return res

    def deserialize(self, data: str) -> TreeNode:
        """Decodes your encoded data to tree.
        """
        def reconPreorder(data):
            tmp = data.pop(0)
            if tmp == "#":
                return None
            head = TreeNode(tmp)
            head.left = reconPreorder(data)
            head.right = reconPreorder(data)
            return head
        data = data.split("!")
        return reconPreorder(data)



# Your Codec object will be instantiated and called as such:
# codec = Codec()
# codec.deserialize(codec.serialize(root))

折纸问题

【题目】 请把一段纸条竖着放在桌子上, 然后从纸条的下边向
上方对折1次, 压出折痕后展开。 此时 折痕是凹下去的, 即折痕
突起的方向指向纸条的背面。 如果从纸条的下边向上方连续对折
2 次, 压出折痕后展开, 此时有三条折痕, 从上到下依次是下折
痕、 下折痕和上折痕。
给定一 个输入参数N, 代表纸条都从下边向上方连续对折N次,
请从上到下打印所有折痕的方向。 例如: N=1时, 打印: down
N=2时, 打印: down down up

def printProcess(i,n,down):
    if i > n:
        return
    printProcess(i+1,n,True)
    print("down" if down else "up",end=" ")
    printProcess(i+1,n,False)
def printAllFolds(n):
    printProcess(1,n,True)
printAllFolds(4)
down down up down down up up down down down up up down up up 

判断一棵二叉树是否是平衡二叉树

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YuvkmfHs-1588470251334)(attachment:image.png)]

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class ReturnData():
    def __init__(self,isb,h):
        self.isb = isb
        self.h = h
class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        def process(head):
            if not head:
                return ReturnData(True,0)
            leftData = process(head.left)
            if not leftData.isb:
                return ReturnData(False,0)
            
            rightData = process(head.right)
            if not rightData.isb:
                return ReturnData(False,0)
            if abs(leftData.h-rightData.h) > 1:
                return ReturnData(False,0)
            return ReturnData(True,max(leftData.h,rightData.h)+1)
        return process(root).isb

判断一棵树是否是搜索二叉树、 判断一棵树是否是完全二叉树

搜索二叉树 中序遍历是升序

# 判断是否为搜索二叉树
def isBST(head):
    if not head:
        return
    stack = []
    res = float('-inf')
    while stack or head:
        if head:
            stack.append(head)
            head = head.left
        else:
            head = stack.pop()
            if head.val > res :
                head = head.right
            else:
                return False
    return True                   

完全二叉树

(1)有右孩子,没有左孩子 False

(2)有左孩子,没有右孩子 后面遍历的结点全是叶节点

(3)左右都没有 后面遍历的结点全是叶节点

(4)左右都有 继续判断

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    def isCompleteTree(self, root: TreeNode) -> bool:
        if not root:
            return True
        queue = [root]
        # 是否开启叶节点判断
        flag = False
        while queue:
            tmp = queue.pop(0)
            l = tmp.left
            r = tmp.right
            # 右孩子存在左孩子不存在
            # flag=True 如果不是叶结点 not(not r and not l)
            if r and not l or (flag and not(not r and not l)):
                return False
            if l:
                queue.append(l)
            if r:
                queue.append(r)
            else:
                flag = True
        return True

已知一棵完全二叉树, 求其节点的个数

要求: 时间复杂度低于O(N), N为这棵树的节点个数

遍历左边界 得到二叉树高度 h

遍历右边界 到达最后一层,则为满二叉树

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def countNodes(self, root: TreeNode) -> int:

        def bs(node,level,h):
            # node 在第几层  h总高度  返回值为node为头的总节点数
            if level == h:
                return 1
            if mostLeftLevel(node.right,level+1) == h:
                # 右子树的  左高度触底,则左子树为满二叉树,递归求其右子树即可
                return (1<<(h-level)) + bs(node.right,level+1,h)
            else:
                # 右子树的  左高度没有触底,则右子数为满二叉树(高度h-level-1)左子数递归即可 
                return (1<<(h-level-1)) + bs(node.left,level+1,h)
            
            
        def mostLeftLevel(node,level):
            while node:
                level += 1
                node = node.left
            return level - 1
        if not root:
            return 0
        return bs(root,1,mostLeftLevel(root,1))
    

你可能感兴趣的:(数据结构与算法)