二叉树的各种算法(一)python

即将进入秋招,楼主后续会复习一些数据结构算法题目python版本+机器学习主流算法的原理及推导,有空更。

今天是关于二叉树元素添加(队列实现),前序、中序、后序遍历的递归与栈实现,最大深度与最大距离的递归实现

PS:楼主大致就用了一个例子测试了下,暂时没有毛病,若有bug私信或评论我修改,如有雷同,就当我是抄你的,若还是有版权纠纷私信我,你们是大佬我是小弟,向大佬低头(其实这些算法不可能完全是我凭空想出来的,肯定是我以前见到过这些思路,此次回忆实现而已)。

  • 首先定义节点class和二叉树class,这里树初始为空节点
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Jul 31 23:06:50 2017

@author: xuhy
"""
class Node():#节点class,初始值为None
    def __init__(self,value=None,lchild=None,rchild=None):
        self.value=value
        self.lchild=lchild
        self.rchild=rchild

class BTree():#BTree二叉树class
    def __init__(self,root=Node()):#初始化默认root为一个Node()
        self.root=root
  • 然后是层次添加元素,用了一个队列
    def add(self,new):#二叉树层次添加
        #利用一个队列,以根节点开始,如果这一层没有空位,则全部入队列
        #依次检查下一层,如果有空位则直接填补空位,若没有则节点入队列
        if self.root.value==None:
            self.root=Node(new)
        else:
            stack=[]
            stack.append(self.root)
            while stack:
                node=stack.pop(0)#因为是队列,所以是pop(0)
                if node.lchild==None:
                    node.lchild=Node(new)
                    return
                elif node.rchild==None:
                    node.rchild=Node(new)
                    return
                else:
                    stack.append(node.lchild)
                    stack.append(node.rchild)
  • 接下来是前序、中序、后序的递归实现
    #前序遍历递归
    def front_digui(self,root):
        #这里解释下or,or左边表示叶子节点子节点,or右边表示空树
        if root==None or root.value==None:
            return
        else:
            print(root.value)
            self.front_digui(root.lchild)
            self.front_digui(root.rchild)

    #中序递归
    def mid_digui(self,root):
        if root==None or root.value==None:
            return
        else:
            self.mid_digui(root.lchild)
            print(root.value)
            self.mid_digui(root.rchild)

    #后序递归
    def back_digui(self,root):
        if root==None or root.value==None:
            return
        else:
            self.back_digui(root.lchild)
            self.back_digui(root.rchild)   
            print(root.value)
  • 然后是三种遍历的栈实现,个人觉得后序有点厉害
    #前序遍历,一个栈stack一个指示节点node
    #总的思路就是,一路走到黑先把左边走到底,顺便print+入栈,
    #然后依次从栈里取节点,指示node更正,继续上述操作
    def front_stack(self,root):
        if root.value==None:
            return
        node=root
        stack=[]
        while node or stack:
            while node:
                stack.append(node)
                print(node.value)
                node=node.lchild
            node=stack.pop()
            node=node.rchild
    #中序遍历,一个栈stack一个指示节点node
    #总的思路为,一路走到左边黑,顺便入栈
    #然后依次出栈,print+指示node更正,继续上述操作      
    def mid_stack(self,root):
        if root.value==None:
            return
        node=root
        stack=[]
        while node or stack:
            while node:
                stack.append(node)
                node=node.lchild
            node=stack.pop()
            print(node.value)
            node=node.rchild

    #后续遍历,两个栈stack一个指示节点node
    #个人认为最难,因为根节点最后输出,直接看代码吧
    def back_stack(self,root):
        if root.value==None:
            return
        node=root
        stack1=[]
        stack2=[]
        stack1.append(node)
        while stack1:
            node=stack1.pop()
            stack2.append(node)
            if node.lchild:
                stack1.append(node.lchild)
            if node.rchild:
                stack1.append(node.rchild)
        while stack2:
            node=stack2.pop()
            print(node.value)
  • 接着是递归求二叉树的最大深度与距离,其中最大距离好像是《编程之美》上面的一道题目,这里连同最大深度一起输出,如果理解上有困难,读者可以拿出笔和纸画一画,理一理。
    #同时计算二叉树最大深度和距离,利用递归思想recur
    #思路就是,树的最大深度为左子树或右子树的最大深度+1;
    #最大距离就是,树的最大距离要么是左子树最大距离,要么是右子树最大距离
    #再要么是左子树最大深度+右子树最大深度+1+1,三者取最大值;
    #这里认为单节点树深度为0,距离为0
    def get_depth_dis(self,root):
        if root.value==None:
            return
        elif root.lchild==None and root.rchild==None:
            return 0,0
        elif root.lchild==None and root.rchild!=None:
            return (self.get_depth_dis(root.rchild)[0]+1,
                    max(self.get_depth_dis(root.rchild)[1],
                        self.get_depth_dis(root.rchild)[0]+1))
        elif root.rchild==None and root.lchild!=None:
            return (self.get_depth_dis(root.lchild)[0]+1,
                    max(self.get_depth_dis(root.lchild)[1],
                        self.get_depth_dis(root.lchild)[0]+1))
        else:
            return (max(self.get_depth_dis(root.lchild)[0]+1,
                        self.get_depth_dis(root.rchild)[0]+1),
                    max(self.get_depth_dis(root.lchild)[1],
                        self.get_depth_dis(root.rchild)[1],
                        self.get_depth_dis(root.lchild)[0]+1+
                        self.get_depth_dis(root.rchild)[0]+1))

这次先到这里,实习的事儿也得做,就偶尔抽点时间练下手。
下次应该是层次遍历、中序+其他序重构二叉树、二叉树镜像。。。
see you!
pps:有空还想试验下GAN的几个版本,如果做了也会更新,不知道我的1060受得了不,天杀的黄牛&旷工,还我1080ti!
哎,暑假完又要回实验室搬砖啦,毕竟不能坑老板呀,恩我是电气工程的。。。

你可能感兴趣的:(二叉树的各种算法(一)python)