python 实现二叉树相关算法

一、构建与遍历二叉树

基本性质
1)在二叉树的第i层上最多有2i-1 个节点 。(i>=1)
2)二叉树中如果深度为k,那么最多有2k-1个节点。(k>=1)
3)在完全二叉树中,具有n个节点的完全二叉树的深度为[log2n]+1,其中[log2n]是向下取整。向下取整就是小数点后面的数字无论多少,都只取前面的整数。

4)二叉树的存储可以顺序存储即数组形式,也可以链式存储。
 

class Node(object):
    def __init__(self,item):
        self.key=item
        self.left=None
        self.right=None
class BinaryTree(object):
    def __init__(self):
        self.root=None

    def addNode(self,item):
        new_node = Node(item)
        if self.root is None:
           self.root=new_node
        else:
            stack=[]
            stack.append(self.root)
            while True:
                node=stack.pop(0)
                if node.left is None:
                    node.left=new_node
                    return
                elif node.right is None:
                    node.right=new_node
                    return
                else:
                    stack.append(node.left)
                    stack.append(node.right)

    def traverse(self):  #层次遍历
        if self.root is None:
            return None
        else:
            s=[]
            s.append(self.root)
            while len(s) > 0:
                node = s.pop(0)
                print(node.key)
                if node.left is not None:
                    s.append(node.left)
                if node.right is not None:
                    s.append(node.right)

#一层层打印
def
Print(self, pRoot): if pRoot is None: return [] l=[] s=[] s.append(pRoot) while len(s)>0: length=len(s) v=[] for i in range(length): tmp=s.pop(0) v.append(tmp.val) if tmp.left: s.append(tmp.left) if tmp.right: s.append(tmp.right) l.append(v) return l


def preOrder(self,root):
        if root is None:
            return None
        print(root.key)
        self.preOrder(root.left)
        self.preOrder(root.right)

    def inOrder(self,root):
        if root is None:
            return None

        self.inOrder(root.left)
        print(root.key)
        self.inOrder(root.right)

    def postOrder(self,root):
        if root is None:
            return None

        self.postOrder(root.left)
        self.postOrder(root.right)
        print(root.key)

 之字形打印二叉树

def print(root):
    if root is None:
        return None
    s1=[]
    s2=[]
    s1.append(root)#靠两个栈交替左右压入栈,实现左右交替输出,形成之字形打印
    while len(s1)>0 or len(s2)>0:
        while len(s1)>0:
            tmp=s1.pop()
            print(tmp.value)
            if tmp.left is not None:
                s2.append(tmp.left)
            if tmp.right is not None:
                s2.append(tmp.right)
        while len(s2)>0:
            tmp=s2.pop()
            print(tmp.value)
            if tmp.right is not None:
                s1.append(tmp.right)
            if tmp.left is not None:
                s1.append(tmp.left)

非递归前序遍历:

def PreOrderWithoutRecursion(root):
    if root is None:
        return
    s=[]
    p=root
    while len(s)>0 or p is not None:
        if p is not None:
            print(p.key)
            s.append(p)
            p=p.left
        else:
            p=s.pop()
            p=p.right

非递归中序遍历:

def InOrderWithoutRecursion(root):
    if root is None:
        return
    s=[]
    p=root
    while len(s)>0 or p is not None:
        if p is not None:
            s.append(p)
            p=p.left
        else:
            p=s.pop()
            print(p.key)
            p=p.right

非递归后序遍历:

def PostOrderWithoutRecursion(root):
    if root is None:
        return
    s=[]
    p=root
    lastVisit=None
    while p is not None:
        s.append(p)
        p=p.left
    while len(s)>0:
        p=s.pop()
        if p.right==None or lastVisit==p.right:
            print(p.key)
            lastVisit=p
        else:
            s.append(p)
            p=p.right
            while p is not None:
                s.append(p)
                p=p.left

二、二叉树的宽度与深度

def treeDepth(root):
    if root is None:
        return 0
    nleft=treeDepth(root.left)+1
    nright=treeDepth(root.right)+1
    return nleft if nleft > nright else nright

#求解二叉树的宽度,节点数最多的一层的节点数即为二叉树的宽度
def treeWidth(root):
    if root is None:
        return 0
    max_width=0
    s=[]
    s.append(root)
    while len(s)>0:
        width=len(s)
        if width>max_
            max_width=width
        for i in range(width):
            node=s.pop(0)
            if node.left is not None:
                s.append(node.left)
            if node.right is not None:
                s.append(node.right)

    return max_width

 三、判断是否为子树

#如果两个节点值相同,则继续判断下面节点值是否也相等
def
isPart(pRoot1,pRoot2): if pRoot2 is None: return True if pRoot1 is None: return False if pRoot1.val!=pRoot2.val: return False return isPart(pRoot1.left,pRoot2.left) and isPart(pRoot1.right,pRoot2.right) def HasSubtree(pRoot1, pRoot2): res=False if pRoot1 is not None and pRoot2 is not None: if pRoot1.val==pRoot2.val: res=isPart(pRoot1,pRoot2) if not res: res=HasSubtree(pRoot1.left,pRoot2) if not res: res=HasSubtree(pRoot1.right,pRoot2) return res

 四、判断是否为平衡二叉树

def TreeDepth(self,root):
        if root is None:
            return 0
        nleft=self.TreeDepth(root.left)
        nright=self.TreeDepth(root.right)
        return nleft+1 if nleft>nright else nright+1

def IsBalanced_Solution(self, pRoot):
    isBalance=True
    if pRoot is None:
        return isBalance
    leftDepth=self.TreeDepth(pRoot.left)
    rightDepth=self.TreeDepth(pRoot.right)
    if abs(leftDepth-rightDepth)>1:
        isBalance=False
    return isBalance and self.IsBalanced_Solution(pRoot.left) and self.IsBalanced_Solution(pRoot.right)

五、判断是否为对称二叉树

def isSame(self,left,right):
        if left and right :
            if left.val==right.val:
                return self.isSame(left.left,right.right) and self.isSame(left.right,right.left)
            else:
                return False
        elif not left and not right:
            return True
        else:
            return False
def isSymmetrical(self, pRoot):
    if pRoot is None:
        return True
    return self.isSame(pRoot.left,pRoot.right)

 六、序列化与反序列化

def Serialize(self, root):
        if root is None:
            return '#'
        return str(root.val)+self.Serialize(root.left)+self.Serialize(root.right)
def Deserialize(self, s):
    if len(s)<=0:
        return None
    root=None
    val=s.pop(0)
    if val!='#':
        root=TreeNode(int(val))
        root.left=self.Deserialize(s)
        root.right=self.Deserialize(s)
    return root

七、查找二叉树某个值的路径(先根方式)

def findval(root,val):
    if root is None:
        return None
    s=[]
    p=root
    path=[] #利用先根遍历的方式进行查找,path保存那些右子树不为空的根节点,进入path说明遍历过了,以便后续判断何时出栈。
    while len(s)>0 or p is not None:
        if p is not None:
            if p in path:
                s.pop()#如果在path中了,说明之前遍历过来,就直接出栈吧,不用再向下子树遍历了
            else:
                s.append(p)
                if p.key==val:
                    return s
                p=p.left
        else:
            p=s[len(s)-1]#暂时先不出栈,看看右子树是否为空,右子树不为空,就暂时不出栈
            if p.right is None or p in path:#右子树为空的,或者之前遍历过的就直接出栈吧
                s.pop()
                p=None
            else:
                path.append(p) #之前没遍历过的且其右子树不为空,那就先不出栈了,放入path中,表示遍历过了。
                p=p.right

 例如上图中:E的路径就是A,C ,E。  F的路径就是A,C,F.

 

参考来源:https://www.jianshu.com/p/bf73c8d50dc2

 

原文地址:https://www.cnblogs.com/gczr/p/8033104.html