算法---树的遍历

1.先序遍历

(1)递归

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

class Solution:
    def preorderTraversal(self,root):
        '''
        递归,时间复杂度O(n),空间复杂度平均O(logn),最坏情况下O(n)
        :param root:
        :return:
        '''
        if root:
            print(root.val)
        else:
            return
        self.preorderTraversal(root.left)
        self.preorderTraversal(root.right)

(2)非递归

非递归,时间复杂度O(n),空间复杂度O(n)
思路:

1)申请一个新的栈,把头结点压入栈中
2)从栈中弹出栈顶节点,记为node,然后打印node节点的值,再将节点node的由孩子先压入stack中,最后将node的左孩子压入stack中
3)不断重复步骤2,直到栈为空,过程结束

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

class Solution:
    def preorderTraversal1(self,root):
        '''
        :param root:
        :return:
        '''
        if root == None:
            return

        res = []
        stack = [root]
        while stack:
            node = stack.pop()
            print(node.val)
            res.append(node.val)
            if node.right:
                stack.append(node.right)
            if node.left:
                stack.append(node.left)
        return res

2.中序遍历

(1)递归

递归,时间复杂度O(n),空间复杂度平均O(logn),最坏情况下O(n)

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

class Solution:
    def inorderTraversal(self,root):
        '''
        :param root:
        :return:
        '''
        if root == None:
            return
        self.inorderTraversal(root.left)
        print(root.val)
        self.inorderTraversal(root.right)

(2)非递归

非递归,时间复杂度O(n),空间复杂度O(n)
思路:

1)申请一个新的栈,初始时,令变量node=head
2)先把node节点压入栈中,对以node节点为头的整棵子树来说,依次把左边界压入栈中,即不停的令node=node.left,然后重复步骤2
3)不断重复步骤2,直到发现node为空,此时,从栈中弹出一个节点,记为node,打印node的值,并且让node=node.right,然后继续重复步骤2
4)当stack为空且cur为空时,整个过程停止.

class Solution:
    def inorderTraversal1(self,root):
        '''
        :param root:
        :return:
        '''
        if root == None:
            return
        res = []
        stack = []
        node = root
        while stack or node:
            if node:
                stack.append(node)
                node = node.left
            else:
                node = stack.pop()
                res.append(node.val)
                node = node.right
        return res

3.后序遍历

(1)递归

递归,时间复杂度O(n),空间复杂度平均O(logn),最坏情况下O(n)

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

class Solution:
    def posorderTraversal(self,root):
        '''
        :param root:
        :return:
        '''
        if root == None:
            return
        self.posorderTraversal(root.left)
        self.posorderTraversal(root.right)
        print(root.val)

  

(2)非递归

a.两个栈

非递归,时间复杂度O(n),空间复杂度O(n)
思路:用两个栈实现后序遍历
1)申请一个栈,记为s1,然后将头结点head压入栈Ss1中;
2)从s1中弹出的节点记为cur,然后依次将cur的左孩子和右孩子压入s1中;
3)从整个过程中,每一个从s1中弹出的节点都放进s2中;
4)不断重复步骤2和步骤3,直到s1为空,过程停止;
5)从s2中依次弹出节点并打印,打印的顺序就是后序遍历的顺序.

class Solution:
    def posorderTraversal1(self,root):
        '''
        :param root:
        :return:
        '''
        if not root:
            return []
        s1,s2 = [root],[]
        while s1:
            cur = s1.pop()
            s2.append(cur.val)
            if cur.left:
                s1.append(cur.left)
            if cur.right:
                s1.append(cur.right)
        return s2[::-1]

b.一个栈

思路:用一个栈实现后序遍历
申请一个栈,将头结点压入栈中,同时设置变量h和c,h代表最近一次弹出并打印的节点,c代表stack的栈顶节点,初始时h为头结点,c为null

def posorderTraversal2(self,root):
    '''
    :param root:
    :return:
    '''
    if not root:
        return []
    res = []
    cur = [root]
    while cur:
        node = cur[-1]
        if node.left and node.left != root and node.right != root:
            cur.append(node.left)
        elif node.right and node.right != root:
            cur.append(node.right)
        else:
            res.append(cur.pop().val)
            root = node
    return res

4.层次遍历

(1)递归

思路:每次遍历到新层,层数+1,

class Solution:
    def levelOrder(self,root,level,result):
        '''
        递归,按层输出
        :param root:
        :param level:
        :param result:
        :return:
        '''
        if root == None:
            return
        if level == len(result): # 如果遍历到了新层,就新建一个[]用来存放新层的值
            result.append([])
        result[level].append(root.val)
        if root.left:
            self.levelOrder(root.left,level+1,result)
        if root.right:
            self.levelOrder(root.right,level+1,result)

    def levelOrder1(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        level,result = 0,[]
        self.levelOrder(root,level,result)
        return result

(2)非递归

思路:用一个队列记录

def levelOrder2(self,root):
    '''
    思路:队列
    用队列存储节点,每次左边出一个节点,如果该节点有左右节点,就将左右节点入队列,直到队列空为止
    :param root:
    :return:
    '''
    from collections import deque
    if root == None:
        return
    queue = deque()
    queue.append(root)
    res = []
    while queue:
        node = queue.popleft()
        res.append(node.val)
        if node.left:
            queue.append(node.left)
        if node.right:
            queue.append(node.right)

  

 

转载于:https://www.cnblogs.com/nxf-rabbit75/p/11491809.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值