剑指offer--二叉搜索树的后序遍历序列;二叉树中和为某一值的路径;二叉搜索树与双向链表;最小的K个数;二叉树的下一个结点;把二叉树打印成多行;二叉搜索树的第k个结点;序列化二叉树

二叉搜索树的后序遍历序列

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

代码

# -*- coding:utf-8 -*-
class Solution:
    def VerifySquenceOfBST(self, sequence):
        # write code here
        if sequence == []:
            return False
        # 先将最后一位,即根节点取出
        rootnum = sequence[-1]
        index = None
        # 在取出后,直接删除,比较有利于后面代码的编写
        del sequence[-1]
        # 进行每一个数组的循环,如果出现大于最后一位的情况,那么久记录下当前节点值
        # 在之后继续进行判断,如果出现大于的数字后,会出现小于的数字,那么表示不是后续遍历的结果
        for i in range(len(sequence)):
            if index == None and sequence[i] > rootnum:
                index = i 
            if index != None and sequence[i] < rootnum:
                return False
        # 由于题中对于[]的不同操作,所以需要多次判断,如果子节点为[],那么做节点为True,否则继续进行判断
        if sequence[:index] == []:
            leftnode = True
        else:
            leftnode = self.VerifySquenceOfBST(sequence[:index])
        if sequence[index:] == []:
            rightnode = True
        else:
            rightnode = self.VerifySquenceOfBST(sequence[index:])
        # 需要同时判断两个数值才能确定是后序遍历
        return leftnode and rightnode
        

二叉树中和为某一值的路径

输入一颗二叉树的根节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)

代码

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
import copy
class Solution:
    # 返回二维列表,内部每个列表表示找到的路径
    def FindPath(self, root, expectNumber):
        # 如果为None,返回NOne
        if root == None:
            return []
        # 需要一个返回列表
        ret = []
        # 首先对二叉树进行广度优先遍历,需要将每个经过的list记录下来
        support = [root]
        supportList = [[root.val]]
        while support:
            tmpNode = support[0]
            tmpNodelist = supportList[0]
            # 需要设置当到达叶子节点后,是否符合所需要的加和
            if tmpNode.left == None and tmpNode.right == None:
                numsum = 0
                for i in tmpNodelist:
                    numsum += i 
                if numsum == expectNumber:
                    ret.insert(0,tmpNodelist)
            # 分别进行左右子树的判断,首先设定循环的条件,并且生成新的列表
            # 在新的列表生成后,加入到列表数组中
            if tmpNode.left:
                support.append(tmpNode.left)
                newList = copy.copy(tmpNodelist)
                newList.append(tmpNode.left.val)
                supportList.append(newList)
            if tmpNode.right:
                support.append(tmpNode.right)
                newList = copy.copy(tmpNodelist)
                newList.append(tmpNode.right.val)
                supportList.append(newList)
            del supportList[0]
            del support[0]
        return ret 

二叉搜索树与双向链表

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

代码

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def Convert(self, pRootOfTree):
        # find_right函数主要是找到当前节点的左节点的最右子节点,可以作为当前根节点的左边节点
        def find_right(node):
            while node.right:
                node = node.right
            return node
        
        if pRootOfTree == None:
            return None
        # 首先进行递归
        leftNode = self.Convert(pRootOfTree.left)
        rightNode = self.Convert(pRootOfTree.right)
        # 先将返回头节点定义为左节点
        retNode = leftNode
        # 然后判断左节点,如果存在,找到其最右节点
        # 否则当前根节点即为返回节点,表明左边没有节点,根节点为最小值
        if leftNode:
            leftNode = find_right(leftNode)
        else:
            retNode = pRootOfTree
        # 将根节点左右节点变化为获取的值,转化为双向链表
        # 对于有节点,返回值即为最左边,所以可以直接赋值
        pRootOfTree.left = leftNode
        pRootOfTree.right = rightNode
        # 同时将所获取值与根节点进行连接
        if leftNode != None:
            leftNode.right = pRootOfTree
        if rightNode != None:
            rightNode.left = pRootOfTree
        # 递归进行获取值,最后返回双向链表
        return retNode

最小的K个数

输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。

代码

# -*- coding:utf-8 -*-
class Solution:
    def GetLeastNumbers_Solution(self, tinput, k):
        # 在本题中,需要使用最小堆的概念,进行创建并修改
        # 创建大根堆,首先使用k个数字组成大根堆,这样可以为接下来的调整做准备
        def createMaxheap(num):
            maxHeap.append(num)
            currentIndex = len(maxHeap)-1
            while currentIndex != 0:
                parentIndex = (currentIndex - 1) >> 1
                if maxHeap[parentIndex] < maxHeap[currentIndex]:
                    #tmp = maxHeap[parentIndex]
                    #maxHeap[parentIndex] = maxHeap[currentIndex]
                    #maxHeap[currentIndex] = tmp
                    maxHeap[parentIndex],maxHeap[currentIndex] = maxHeap[currentIndex],maxHeap[parentIndex]
                else:
                    break 
                # 这一步比较重要,需要多重循环遍历
                currentIndex = parentIndex
        # 对大根堆进行对比,将根节点进行替换,可以保证进入的数字是比当前在最大值小的
        def adjustMaxheap(num):
            if num < maxHeap[0]:
                maxHeap[0] = num
            maxHeapLen = len(maxHeap)
            index = 0
            while index < maxHeapLen:
                leftindex = index*2 + 1
                rightindex = index*2 + 2
                # 获取左右节点中大的数组下标
                largeindex = 0
                if rightindex < maxHeapLen:
                    if maxHeap[leftindex] < maxHeap[rightindex]:
                        largeindex = rightindex
                    else:
                        largeindex = leftindex
                elif leftindex < maxHeapLen:
                    largeindex = leftindex
                else:
                    break 
                # 如果是小于,那么进行交换,保证最大的数在根节点
                if maxHeap[index] < maxHeap[largeindex]:
                    tmp = maxHeap[index]
                    maxHeap[index] = maxHeap[largeindex]
                    maxHeap[largeindex] = tmp
                index = largeindex
                
        maxHeap = []
        tlen = len(tinput)
        if tlen < k or k < 1:
            return []
        for i in range(tlen):
            if i < k:
                createMaxheap(tinput[i])
            else:
                adjustMaxheap(tinput[i])
        maxHeap.sort()
        return maxHeap
        

二叉树的下一个结点

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

代码

# -*- 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
        # 首先查看右子树如果存在右子树,那么查找到右子树的最左节点,就是下一个节点
        if pNode.right:
            # 这里设置tmpNode为右节点,并判断右节点的左子树
            tmpNode = pNode.right
            while tmpNode.left:
                tmpNode = tmpNode.left
            return tmpNode
        # 如果不存在右子树,那么就查看其父亲节点是否为父亲节点的左子树,如果是,那么就返回
        else:
            # 这里设置tmpNode为当前节点,并判断父亲节点
            tmpNode = pNode
            while tmpNode.next:
                if tmpNode.next.left == tmpNode:
                    ret = tmpNode.next
                    return ret 
                tmpNode = tmpNode.next
            return None
            

把二叉树打印成多行

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

代码

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回二维列表[[1,2],[4,5]]
    def Print(self, pRoot):
        # write code here
        if pRoot == None:
            return []
        stack1 = [pRoot]
        stack2 = []
        ret = []
        while stack1 or stack2:
            if stack1:
                tmpRet = []
                while stack1:
                    tmpNode = stack1[0]
                    del stack1[0]
                    tmpRet.append(tmpNode.val)
                    if tmpNode.left:
                        stack2.append(tmpNode.left)
                    if tmpNode.right:
                        stack2.append(tmpNode.right)
                ret.append(tmpRet)
            if stack2:
                tmpRet = []
                while stack2:
                    tmpNode = stack2[0]
                    del stack2[0]
                    tmpRet.append(tmpNode.val)
                    if tmpNode.left:
                        stack1.append(tmpNode.left)
                    if tmpNode.right:
                        stack1.append(tmpNode.right)
                ret.append(tmpRet)
        return ret 

二叉搜索树的第k个结点

给定一棵二叉搜索树,请找出其中的第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
        # 对二叉搜索树进行中序遍历,依旧是数值的从小到大排序,所以直接递归即可
        ret = []
        def midorder(pRoot):
            if pRoot == None:
                return None
            midorder(pRoot.left)
            ret.append(pRoot)
            midorder(pRoot.right)
        
        midorder(pRoot)
        if len(ret) < k or k < 1:
            return None
        return ret[k-1]

序列化二叉树

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

二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。

二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。

代码

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def Serialize(self, root):
        # 使用前序遍历,将遇到None的情况加一个#号,这样在反序列化时可以很快速的找到能够继续下一个节点的情况
        retList = []
        
        def preOrder(root):
            if root == None:
                retList.append('#')
                return
            retList.append(str(root.val))
            preOrder(root.left)
            preOrder(root.right)
        
        preOrder(root)
        return ' '.join(retList)
    
    def Deserialize(self, s):
        # write code here
        retList = s.split()
        def dePreOrder():
            if retList == []:
                return None
            rootVal = retList[0]
            del retList[0]
            if rootVal == '#':
                return None
            node = TreeNode(int(rootVal))
            leftNode = dePreOrder()
            rightNode = dePreOrder()
            node.left = leftNode
            node.right = rightNode
            return node
        pRoot = dePreOrder()
        return pRoot
            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值