python二叉树的前序遍历、中序遍历、后序遍历的递归法和非递归法,层次遍历和之字形遍历,计算树的深度(递归法和循环法),节点个数,所有值的和

三种主要的遍历思想为:
前序遍历:根结点 —> 左子树 —> 右子树
中序遍历:左子树—> 根结点 —>右子树
后序遍历:左子树—> 右子树 —> 根结点

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    def __init__(self):
        self.X = [] #按顺序储存节点的列表
        
    def preOrder(self,phead):#递归前序遍历,也就是深度优先遍历
        if phead:
            self.X.append(phead.val)
            self.preOrder(phead.left)
            self.preOrder(phead.right)
        return self.X
        
    def midOrder(self,phead):#递归中序遍历
        if phead: 
            self.midOrder(phead.left)
            self.X.append(phead.val)
            self.midOrder(phead.right)
        return self.X
  
    def postOrder(self,phead):#递归后序遍历
        if phead:
            self.postOrder(phead.left)
            self.postOrder(phead.right)
            self.X.append(phead.val)
        return self.X
        
    def preOrderNonRec(self,phead):#非递归前序遍历
        if not phead:
            return
        stack = []
        while phead or stack:        
            while phead:            
                # 从根节点开始,一直找它的左子树            
                self.X.append(phead.val)           
                #将右子树压入栈中            
                stack.append(phead.right)            
                #一直往下找左子树            
                phead = phead.left        
        	# while结束表示当前节点phead为空,即前一个节点没有左子树了        
        	# 栈中开始弹出上右子树,再重复前面步骤        
        	phead = stack.pop()        
    	return self.X
 
    def midOrderNonRec(self,phead):#非递归中序遍历
        if not phead:
        	return
    	stack = []
    	while phead or stack:
           while phead:
                # 从根节点开始,一直找它的左子树                      
                #将父节点压入栈中            
                stack.append(phead)
                #一直往下找左子树
                phead = phead.left
            # while结束表示当前节点phead为空,即前一个节点没有左子树了
            # 栈中开始弹出上父节点,存储值,然后搜索父节点的右子树,重复前面步骤 
            phead = stack.pop() 
            self.X.append(phead.val) 
            phead = phead.right
        return self.X
    
    def postOrderNonRec(self,phead):#非递归前序遍历
        if not phead:
            return
        stack = []
        while phead or stack:
            while phead:
                # 从根节点开始,一直找它的左子树
                stack.append(phead)
                #一直往下找左子树
                if phead.left:
                    phead = phead.left
                else:
                    phead = phead.right
            # while结束表示当前节点phead为空,即前一个节点没有左子树和右子树的节点
            # 栈中开始弹出,栈顶就是当前应该访问的节点
            phead = stack.pop()
            self.X.append(phead.val)
            #栈不空且当前节点是栈顶的左子节点,那么应当继续去访问栈顶的右子节点
            if len(stack) !=0 and stack[-1].left == phead:
                phead = stack[-1].right
            else:#没有右子树或右子树遍历完毕,不经过第二个while,再从栈中pop一个元素        
                phead = None
    	return self.X
    	
    def BFS(self,phead):#层次遍历,也就是广度优先遍历
        if not phead:
            return
        queue = []
        queue.append(phead)
        self.X.append(phead.val)
        while queue:
            phead = queue.pop(0)
            if phead.left:
                queue.append(phead.left)
                self.X.append(phead.left.val)
            if phead.right:
                queue.append(phead.right)
                self.X.append(phead.right.val)
        return self.X
        
    def zigzagBFS(self,phead):#之字形层次遍历,就需要有层的概念
        if not phead:
            return
        queue = []
        queue.append(phead)
        self.X.append(phead.val)
        count1 = 1
        count2 = 0
        flag = True
        while queue:
            phead = queue.pop(0)
            count1 -= 1
            if phead.left:
                queue.append(phead.left)
                self.X.append(phead.left.val)
                count2 += 1
            if phead.right:
                queue.append(phead.right)
                self.X.append(phead.right.val)
                count2 += 1
             if count1 == 0:
                if flag:
                    #self.X[len(self.X)-count2:len(self.X)].reverse()
                    temp = self.X[len(self.X)-count2:len(self.X)]
                    temp.reverse()
                    self.X[len(self.X)-count2:len(self.X)] = temp
                count1 = count2
                count2 = 0
                flag = not flag
        return self.X
        
    def zigzagBFS2(self,phead):#之字形层次遍历,更简单的写法
        if not phead:
            return
        queue = []
        queue.append(phead)
        #self.X.append(phead.val)
        flag = False
        while queue:
            vals_i = [i.val for i in queue]
            if flag:
                vals_i.reverse()
            flag = not flag
            #self.X.append(vals_i)
            for i in vals_i:
                self.X.append(i)
            tmp_nodes = []            
            for node in queue:                
                if node.left != None:                    
                    tmp_nodes.append(node.left)                
                if node.right != None:                    
                    tmp_nodes.append(node.right)            
            queue = tmp_nodes[:]
        return self.X
        
    def sumNode(self,phead):#计算二叉树中所有值的和
        if not phead:
            return 0
        else:
            return phead.val + self.sumNode(phead.left) + self.sumNode(phead.right)
            
    def countNode(self,phead):#计算二叉树的节点个数
        if not phead:
            return 0
        else:
            return 1 + self.countNode(phead.left) + self.countNode(phead.right)
            
    def TreeDeep(self,phead):#递归法计算二叉树的深度
        if not phead:
            return 0
        left = self.TreeDeep(phead.left) + 1
        right = self.countNode(phead.right) + 1
        return left if left > right else right
        
    def TreeDeepNonRec(self,phead):#循环法计算二叉树的深度
        if not phead:
            return 0
        else:
            self.X.append(phead)
            return self.find()
            
    def find(self):
        i = 1#当前层节点数量
        Y = []
        while len(self.X) != 0:
            j = 0#统计下一层节点数量
            while i > 0:
                #提取该层的节点
                node = self.X.pop(0)
                if i == 1:
                    #在该层提取一个节点
                    Y.append(node.val)
                if node.left != None:
                    # 添加下一层节点
                    self.X.append(node.left)
                    j += 1
                if node.right != None:
                    # 添加下一层节点
                    self.X.append(node.right)
                    j += 1
                i -= 1
            i = j
        return len(Y)
        
S = Solution()
a1 = TreeNode(10)
a2 = TreeNode(5)
a3 = TreeNode(12)
a4 = TreeNode(4)   
a5 = TreeNode(7)
a1.left = a2
a1.right = a3
a2.left = a4
a2.right = a5
print(S.zigzagBFS2(a1))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值