二叉树的遍历:先序、中序、后序 (递归)

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

class BinaryTreeTraversal:
    def recuPreOrderTraversal(self, pRoot):
        '''
        递归先序遍历:读取根节点,然后分别读取左右子节点
        '''
        if not pRoot:
            return []
        result = []
        result.append(pRoot.val)
        if pRoot.left:
            left = self.recuPreOrderTraversal(pRoot.left)
            result.extend(left)

        if pRoot.right:
            right = self.recuPreOrderTraversal(pRoot.right)
            result.extend(right)
        return result
    
    def notRecuPreOrderTraversal(self, pRoot):
        '''
        非递归先序遍历:用栈来存储元素,每次读取栈顶元素,然后分别将它的右孩子和左孩子入栈,
        根据栈“先进后出”的特性,在读取的时候可以保证先遍历左孩子,再遍历右孩子
        '''
        result = []
        if not pRoot:
            return result
        treeNodeStack = []
        treeNodeStack.append(pRoot)
        while treeNodeStack:
            pNode = treeNodeStack.pop(-1)
            result.append(pNode.val)
            if pNode.right:
                treeNodeStack.append(pNode.right)
            if pNode.left:
                treeNodeStack.append(pNode.left)
        return result
    
    def notRecuPreOrderTraversal2(self, pRoot):
        '''
        先读取根节点,并把它入栈,然后指向它的左子树,没有左子树的时候依次出栈,并读取每个节点的右子树
        '''
        if not pRoot:
            return []
        result = []
        nodeStack = []
        while pRoot or nodeStack:
            while pRoot:
                result.append(pRoot.val)
                nodeStack.append(pRoot)
                pRoot = pRoot.left
            if nodeStack:
                pRoot = nodeStack.pop(-1).right
        return result

    def recuInOrderTraversal(self, pRoot):
        if not pRoot:
            return []
        result = []
        if pRoot.left:
            left = self.recuInOrderTraversal(pRoot.left)
            result.extend(left)
        result.append(pRoot.val)
        if pRoot.right:
            right = self.recuInOrderTraversal(pRoot.right)
            result.extend(right)
        return result
    
    def notRecuInOrderTraversal(self, pRoot):
        '''
        同先序遍历非递归,不过读取数值不在入栈的时候,而是在出栈的时候
        '''
        if not pRoot:
            return []
        result = []
        nodeStack = []
        while pRoot or nodeStack:
            while pRoot:
                nodeStack.append(pRoot)
                pRoot = pRoot.left
            if nodeStack:
                pRoot = nodeStack.pop(-1)
                result.append(pRoot.val)
                pRoot = pRoot.right
        return result
    
    def recuLastOrderTraversal(self, pRoot):
        '''
        递归实现后序遍历
        '''
        if not pRoot:
            return []
        result = []
        if pRoot.left:
            left = self.recuLastOrderTraversal(pRoot.left)
            result.extend(left)
        if pRoot.right:
            right = self.recuLastOrderTraversal(pRoot.right)
            result.extend(right)
        result.append(pRoot.val)
        return result
    
    def notRecuLastOrderTraversal(self, pRoot):
        '''
        非递归实现后序遍历
        目标是实现左右根的输出顺序,逆序思考就是根右左,这就是先序遍历转为先右后左的方法
        '''
        if not pRoot:
            return []
        result = []
        nodeStack = []
        while pRoot or nodeStack:
            while pRoot:
                result.append(pRoot.val)
                nodeStack.append(pRoot)
                pRoot = pRoot.right
            if nodeStack:
                pRoot = nodeStack.pop(-1)
                pRoot = pRoot.left
        return result[::-1]

if __name__ == '__main__':
    pRoot = TreeNode(1)
    pRoot.left = TreeNode(2)
    pRoot.right = TreeNode(3)
    pRoot.left.left = TreeNode(4)
    pRoot.left.right = TreeNode(5)
    pRoot.right.left = TreeNode(6)
    pRoot.right.right = TreeNode(7)

    traversal = BinaryTreeTraversal()
    assert(traversal.recuPreOrderTraversal(pRoot)==[1,2,4,5,3,6,7])
    assert(traversal.notRecuPreOrderTraversal(pRoot)==[1,2,4,5,3,6,7])
    assert(traversal.notRecuPreOrderTraversal2(pRoot)==[1,2,4,5,3,6,7])

    assert(traversal.recuInOrderTraversal(pRoot)==[4,2,5,1,6,3,7])
    assert(traversal.notRecuInOrderTraversal(pRoot)==[4,2,5,1,6,3,7])

    assert(traversal.recuLastOrderTraversal(pRoot)==[4,5,2,6,7,3,1])
    assert(traversal.notRecuLastOrderTraversal(pRoot)==[4,5,2,6,7,3,1])

    print("Conguratulations!!!")

 

你可能感兴趣的:(剑指offer)