数据结构(剑指offer)(树)(python)

题目描述

给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。

# -*- coding:utf-8 -*-
# class TreeLinkNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#         self.next = None
class Solution:
    def GetNext(self, pNode):
        # write code here
        # write code here
        if not pNode:
            return pNode
        if pNode.right:             #有右孩子
            left1=pNode.right        #遍历右孩子的左孩子
            while left1.left:
                   left1=left1.left
            return left1
        p=pNode
        while pNode.next:          #有父节点
            tmp=pNode.next          #将父节点赋给tmp
            if tmp.left==pNode:      #pNone若是父节点的左孩子
                return tmp            #返回父节点
            pNode=tmp                   #否则向上回溯

题目描述

请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def isSymmetrical(self, pRoot):
        # write code here
        def is_name(p1,p2):
            if not p1 and not p2:
                return True
            if (p1 and p2) and p1.val == p2.val:
                return is_name(p1.left,p2.right) and is_name(p1.right,p2.left)
            return False
        if not pRoot:
            return True
        if not pRoot.left and pRoot.right:
            return False
        if pRoot.left and not pRoot.right:
            return False
        return is_name(pRoot.left,pRoot.right)

题目描述

请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。

解题思路
先给定一个二叉树的样式: 
 
前段时间做过一道题,其要求是: 
从上往下打印出二叉树的每个节点,同层节点从左至右打印。要求的输出样式是:[1, 2, 3, 4, 5, 6, 7]。这样一道题只需要按序将节点打印出来即可,可利用列表,将新节点存入列表的尾端,并从列表的头部依次打印存入的节点值即可,具体代码见链接。 
而这道题所不同的地方是:其要求输出的样式是:[[1], [3,2], [4,5,6,7]]。和上段中的题目相比,这道题不仅要求按序输出节点值,还要求包含以下信息: 
1. 每一层所包含的树节点; 
2. 偶数层的树节点需倒序。 
所以求解这道题的思路可以说是上一题的升级版,我们同样可以利用列表存储节点,但不同的是列表每次只存储一层的节点,在遍历当前层节点的同时,存储下一层的节点,以此类推。面对要求的偶数层倒序,亦有两种解题思路,第一种是:获取到所有节点的值后,将偶数层的节点值倒序。第二种则是在获取节点的值的时候就倒序存入。以下给出两种方式的Python代码:

Python代码
方式1: 
1. 按序获取每一层节点的值; 
2. 将偶数层节点的值倒序。
 

def Print(self, pRoot):
    resultArray = []
    if not pRoot:
        return resultArray
    curLayerNodes = [pRoot]
    isEvenLayer = True
    while curLayerNodes:
        curLayerValues = []
        nextLayerNodes = []
        isEvenLayer = not isEvenLayer
        for node in curLayerNodes:
            curLayerValues.append(node.val)
            if node.left:
                nextLayerNodes.append(node.left)
            if node.right:
                nextLayerNodes.append(node.right)
        curLayerNodes = nextLayerNodes
        resultArray.append(curLayerValues[::-1]) if isEvenLayer else resultArray.append(curLayerValues)
    return resultArray

方式2: 
获取每一层的节点的值时,如果是偶数层,则将每个节点的值插入到列表的头部,即实现了获取节点值时如果是偶数层则倒序排列的效果:

def Print2(self, pRoot):
    resultArray = []
    if not pRoot:
        return resultArray
    curLayerNodes = [pRoot]
    isEvenLayer = True
    while curLayerNodes:
        curLayerValues = []
        nextLayerNodes = []
        isEvenLayer = not isEvenLayer
        for node in curLayerNodes:
            curLayerValues.insert(0, node.val) if isEvenLayer else curLayerValues.append(node.val)
            if node.left:
                nextLayerNodes.append(node.left)
            if node.right:
                nextLayerNodes.append(node.right)
        curLayerNodes = nextLayerNodes
        resultArray.append(curLayerValues)
    return resultArray

题目描述

从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回二维列表[[1,2],[4,5]]
        # write code 
    def Print(self, pRoot):
        resultArray = []
        if not pRoot:
            return resultArray
        curLayerNodes = [pRoot]
        while curLayerNodes:
            curLayerValues = []
            nextLayerNodes = []
            for node in curLayerNodes:
                curLayerValues.append(node.val)
                if node.left:
                    nextLayerNodes.append(node.left)
                if node.right:
                    nextLayerNodes.append(node.right)
            curLayerNodes = nextLayerNodes
            resultArray.append(curLayerValues)
        return resultArray

题目描述

请实现两个函数,分别用来序列化和反序列化二叉树

思路:二叉树的序列化就是按照某种顺序遍历二叉树,遇到空结点是在遍历输出序列中 
加入某个特殊字符进行标识,反序列化就是按照同样的规则将一个序列还原为一颗二叉树。 
这里采用前序遍历的顺序进行序列化

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    flag = -1
    def Serialize(self, root):
        # write code here
        if not root:
            return '#'
        return str(root.val) + ',' + self.Serialize(root.left) + ',' + self.Serialize(root.right)
     
    def Deserialize(self, s):
        # write code here
        self.flag += 1
         
        l = s.split(',')
        if self.flag >= len(s):
            return None
         
        root = None
        if l[self.flag] != '#':
            root = TreeNode(int(l[self.flag]))
            root.left = self.Deserialize(s)
            root.right = self.Deserialize(s)
        return root
class Solution:
    def Serialize(self, root):
        valuelist = []
        self.preorder(root, valuelist)
        # 将结点值序列转化为一个字符串
        return ','.join(map(str, valuelist))

    def preorder(self, root, valuelist):
        if not root:
            # 对于空结点,返回#字符加以标识
            valuelist.append('#')
            return None
        valuelist.append(root.val)
        self.preorder(root.left, valuelist)
        self.preorder(root.right, valuelist)

    # write code here
    def Deserialize(self, s):
        valuelist = s.split(',')
        root = self.preorderdes(valuelist)
        return root

    def preorderdes(self, valuelist):
        if len(valuelist) == 0 or valuelist[0] == '':
            return None
        # 遇到#字符,直接删除,返回空结点
        if valuelist[0] == '#':
            del valuelist[0]
            return None
        root = TreeNode(int(valuelist[0]))
        del valuelist[0]
        root.left = self.preorderdes(valuelist)
        root.right = self.preorderdes(valuelist)
        return root
--------------------- 
作者:seven_eleven0711 
来源:CSDN 
原文:https://blog.csdn.net/qq_20141867/article/details/80889257 
版权声明:本文为博主原创文章,转载请附上博文链接!

题目描述

给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8)    中,按结点数值大小顺序第三小结点的值为4。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回对应节点TreeNode

    def KthNode(self, pRoot, k):
        # write code here
        #第三个节点是4
        #前序遍历5324768
        #中序遍历2345678
        #后序遍历2436875
        #所以是中序遍历,左根右
        global result
        result = []
        self.getvalues(pRoot)
        if k<=0 or k>len(result):
            return None
        else:
            return result[k-1]
    def getvalues(self,pRoot):
        if not pRoot:
            return None
        self.getvalues(pRoot.left)
        result.append(pRoot)
        self.getvalues(pRoot.right)

题目描述

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.data=[]
    def Insert(self, num):
        # write code here
        self.data.append(num)
        self.data.sort()
    def GetMedian(self,data):
        # write code here
        length=len(self.data)
        if length%2==0:
            return (self.data[length//2]+self.data[length//2-1])/2.0
        else:
            return self.data[length//2]   #//表示取整数

题目描述

输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

递归设计思路:

A、判断子树根值是否相等。

A1、如果是相等,需要一个可以判断该根左右孩子结点是否相等的递归函数。

A2、如果不等,找大树的左右孩子结点当根结点,递归到A步骤。

# -*- coding:utf-8 -*-
 2 # class TreeNode:
 3 #     def __init__(self, x):
 4 #         self.val = x
 5 #         self.left = None
 6 #         self.right = None
 7 class Solution:
 8     def HasSubtree(self, pRoot1, pRoot2):
 9         # write code here
10         res = False
11         if pRoot1 == None or pRoot2 == None :
12             #根据题干要求返回False
13             return res
14         if pRoot1.val == pRoot2.val:
15             #如果结点相等,Subtree函数负责判断
16             #这两个结点的孩子是否相等
17             res = Solution.Subtree(self, pRoot1, pRoot2)
18         if not res:
19             #当与小树相同的子树不在根部,找大树左子树
20             res = Solution.HasSubtree(self, pRoot1.left, pRoot2)
21         if not res:
22             #左边找到了就不需要再找了
23             res = Solution.HasSubtree(self, pRoot1.right, pRoot2)
24         return res
25     
26     def Subtree(self, pRoot1, pRoot2):
27         #下面两个if位置不能反
28         if pRoot2 == None:    #2遍历完了,1还没遍历完,截止目前为止2跟1是一样的,2就是1的子部分了
29             return True
30         if pRoot1 == None: #2还没遍历完,1已经遍历完了,那2的深度还比1大,2就不是1的子部分了
31             return False
32         if pRoot1.val != pRoot2.val:
33             return False
34         #左右同时相等时
35         return Solution.Subtree(self, pRoot1.left, pRoot2.left) and \
36     Solution.Subtree(self, pRoot1.right, pRoot2.right)        
class Solution:
 2     def HasSubtree(self, pRoot1, pRoot2):
 3         # write code here
 4         if pRoot1 == None or pRoot2 == None :
 5             return False
 6         return Solution.Subtree(self, pRoot1, pRoot2) or \
 7     Solution.HasSubtree(self, pRoot1.left, pRoot2) or \
 8     Solution.HasSubtree(self, pRoot1.right, pRoot2)
 9     
10     def Subtree(self, pRoot1, pRoot2):
11         if pRoot2 == None:
12             return True
13         if pRoot1 == None:
14             return False
15         if pRoot1.val != pRoot2.val:
16             return False
17         return Solution.Subtree(self, pRoot1.left, pRoot2.left) and \
18     Solution.Subtree(self, pRoot1.right, pRoot2.right)

猜你喜欢

转载自blog.csdn.net/weixin_41643439/article/details/87002607