算法--20181109--二叉树中序遍历非递归实现

1.二叉树的中序遍历

首先看一下递归方式的实现方式:

class TreeNode:
    left = None
    right = None
    var = 0
    def __init__(self, var):
        self.var = var
        
def inOrder(root):
    if root == None: 
        return
    inOrder(root.left)
    print (root.var)
    inOrder(root.right)

如果传入节点为空则直接返回,否则递归调用inOrder(root.left)即不断搜寻二叉树最左边节点,当找到最左边节点时,root.left==null调用inorder直接返回,继续执行print函数,输出之后继续执行inOrder(root.right) 即当输出某个节点时,指针应该指向输出节点的右节点

def inOrder2(root):
    if root == None:
        return
    #指针
    p = root
    #栈
    s = []
    while p!=None or len(s)>0:
        #将二叉树的从根到最左节点路径上节点不断入栈
        if(p!=None):
            s.append(p)
            p = p.left
        else:
            #从栈中弹出
            p = s.pop()
            print (p.var)
            #当打印完毕只有  指针指向打印节点的右节点
            p = p.right

2.二叉树的先序遍历:

递归方式实现先序遍历:

def preOrder(root):
    if root == None:
        return
    print(root.var)
    preOrder(root.left)
    preOrder(root.right)

当传入节点非空时,立刻打印该节点,然后依次递归遍历left  right节点 先访问根 然后一直访问根的左节点,直到某个节点左节点为空,此时访问该节点的右节点

非递归实现方式:

def preOrder2(root):
    if root == None:
        return
    p = root
    s = []
    s.append(p)
    while len(s)>0:
        p = s.pop()
        print(p.var)
        if p.right != None:
            s.append(p.right)
        if p.left != None:
            s.append(p.left)

首先将根节点入栈,然后弹出输出节点值,依次判断右 左节点是否为空,当节点非空时,依次入栈,则出栈顺序对应左右,即实现了先序遍历。

3.二叉树的后序遍历:

使用一个指针来遍历树节点   使用一个指针来记录上一个被访问的节点   当访问某个节点时,首先入栈,若该节点左右孩子均为空可以直接访问,若左右孩子其一为空并且上一个访问的节点是其左右孩子则该节点也可以访问,若该节点左右孩子非空,则依次将右左节点入栈。

递归方式实现后序遍历:

def postOrder(root):
    if root == None:
        return
    postOrder(root.left)
    postOrder(root.right)
    print (root.var)

如果root为空,直接返回  递归调用root.left以及root.right 等到root.left==root.right==null时或者上一个被访问的节点是树的左右节点之一,本节点才会输出。

非递归实现方式:

根元素入栈,取出栈顶元素  若该元素左右节点为空 或者上一个被访问的节点非空并且上一个被访问的节点是栈顶元素的左右节点之一,则弹出栈顶元素,输出该元素 标记last=p   否则,说明该节点不能输出则将其右左节点依次入栈。

def postOrder2(root):
    if root == None:
        return
    s = []
    p = root
    s.append(p)
    last = None
    while len(s)>0:
        p = s[len(s)-1]
        if(p.left==None and p.right==None) or (last!=None and p.left==last or p.right==last):
            p = s.pop()
            print (p.var)
            last = p
        else:
            if p.right!=None:
                s.append(p.right)
            if p.left!=None:
                s.append(p.left)

4.二叉树的层序遍历:

利用一个队列,根节点入队  循环遍历 队列中元素依次出队输出  然后 队的左右节点依次入队

def levelOrder(root):
    if root==None:
        return
    q = []
    p = root
    q.append(p)
    while len(q)>0:
        p = q.pop(0)
        print (p.var)
        if p.left!=None:
            q.append(p.left)
        if p.right!=None:
            q.append(p.right)

5.分行打印二叉树

利用一个队列  首先根元素入队  然后循环 每一次循环开始队列中存储上一层元素,首选计算本一层元素总数量size  然后遍历上一层所有元素将元素放置于一个list中,如果该元素左右节点非空,则全部入队,这样一个循环结束,下一层的元素已经全部入队,准备下一次循环的开始

def levelOrder2(root):
    if root==None:
        return
    q = []
    p = root
    q.append(p)
    while len(q)>0:
        size = len(q)
        num = []
        while size>0:          
            p = q.pop(0)
            num.append(p.var)
            if p.left!=None:
                q.append(p.left)
            if p.right!=None:
                q.append(p.right)
            size = size - 1
        print (num)

6.按奇偶行打印二叉树  奇行从左到右   偶行从右到左

将每一行的结果记录到list中然后按照奇偶行决定是否翻转数组

def levelOrder3(root):
    if root==None:
        return
    q = []
    p = root
    q.append(p)
    line = 1
    while len(q)>0:
        size = len(q)
        num = []
        while size>0:          
            p = q.pop(0)
            num.append(p.var)
            if p.left!=None:
                q.append(p.left)
            if p.right!=None:
                q.append(p.right)
            size = size - 1
        if line%2==1:
            print (num)         
        else:
            num.reverse()
            print (num)
        line = line + 1

python中List使用:

猜你喜欢

转载自blog.csdn.net/u014106644/article/details/83903140