一、构建与遍历二叉树

基本性质
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_width:
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

 

python 实现二叉树相关算法的更多相关文章

  1. 二叉树-你必须要懂!(二叉树相关算法实现-iOS)

    这几天详细了解了下二叉树的相关算法,原因是看了唐boy的一篇博客(你会翻转二叉树吗?),还有一篇关于百度的校园招聘面试经历,深刻体会到二叉树的重要性.于是乎,从网上收集并整理了一些关于二叉树的资料,及 ...

  2. python实现二叉树遍历算法

    说起二叉树的遍历,大学里讲的是递归算法,大多数人首先想到也是递归算法.但作为一个有理想有追求的程序员.也应该学学非递归算法实现二叉树遍历.二叉树的非递归算法需要用到辅助栈,算法着实巧妙,令人脑洞大开. ...

  3. 数据结构-二叉搜索树和二叉树排序算法(python实现)

    今天我们要介绍的是一种特殊的二叉树--二叉搜索树,同时我们也会讲到一种排序算法--二叉树排序算法.这两者之间有什么联系呢,我们一起来看一下吧. 开始之前呢,我们先来介绍一下如何创建一颗二叉搜索树. 假 ...

  4. [0x00 用Python讲解数据结构与算法] 概览

    自从工作后就没什么时间更新博客了,最近抽空学了点Python,觉得Python真的是很强大呀.想来在大学中没有学好数据结构和算法,自己的意志力一直不够坚定,这次想好好看一本书,认真把基本的数据结构和算 ...

  5. Python实现各种排序算法的代码示例总结

    Python实现各种排序算法的代码示例总结 作者:Donald Knuth 字体:[增加 减小] 类型:转载 时间:2015-12-11我要评论 这篇文章主要介绍了Python实现各种排序算法的代码示 ...

  6. NLP︱高级词向量表达(一)——GloVe(理论、相关测评结果、R&python实现、相关应用)

    有很多改进版的word2vec,但是目前还是word2vec最流行,但是Glove也有很多在提及,笔者在自己实验的时候,发现Glove也还是有很多优点以及可以深入研究对比的地方的,所以对其进行了一定的 ...

  7. 用Python实现随机森林算法,深度学习

    用Python实现随机森林算法,深度学习 拥有高方差使得决策树(secision tress)在处理特定训练数据集时其结果显得相对脆弱.bagging(bootstrap aggregating 的缩 ...

  8. Python面对对象相关知识总结

    很有一段时间没使用python了,前两天研究微信公众号使用了下python的django服务,感觉好多知识都遗忘了,毕竟之前没有深入的实践,长期不使用就忘得快.本博的主要目的就是对Python中我认为 ...

  9. PAT甲级 二叉树 相关题_C++题解

    二叉树 PAT (Advanced Level) Practice 二叉树 相关题 目录 <算法笔记> 重点摘要 1020 Tree Traversals (25) 1086 Tree T ...

随机推荐

  1. 【Linux】- vi/vim

    所有的 Unix Like 系统都会内建 vi 文书编辑器,其他的文书编辑器则不一定会存在. 但是目前我们使用比较多的是 vim 编辑器. vim 具有程序编辑的能力,可以主动的以字体颜色辨别语法的正 ...

  2. matlab如何将数组中的NAN值去除

        比如我们一组数据,里面有不少的NaN值,如何将其删除掉呢?可以通过find函数来搞定.     我们可以通过importdata('data.txt')将数据文件data.txt导入数组A中. ...

  3. java 文本读取 写入指定长度的内容

  4. C# 面向对象——继承

    继承:代码文字结合理解 class Program { static void Main(string[] args) { //Student s = new Student(); //Driver ...

  5. C# 类反射创建对象实例

    object obj= Activator.CreateInstance(Type  type);

  6. POJ1228:Grandpa's Estate——题解

    http://poj.org/problem?id=1228 题目大意:给一个凸包,问是否为稳定凸包. ———————————————————————— 稳定凸包的概念为:我任意添加一个点都不能使这个 ...

  7. 洛谷4578 & LOJ2520:[FJOI2018]所罗门王的宝藏——题解

    https://www.luogu.org/problemnew/show/P4578 https://loj.ac/problem/2520 有点水的. 先转换成图论模型,即每个绿宝石,横坐标向纵坐 ...

  8. [Leetcode] single number 找单个数

    Given an array of integers, every element appears twice except for one. Find that single one. Note:  ...

  9. bzoj2733: [HNOI2012]永无乡(splay+启发式合并/线段树合并)

    这题之前写过线段树合并,今天复习Splay的时候想起这题,打算写一次Splay+启发式合并. 好爽!!! 写了长长的代码(其实也不长),只凭着下午的一点记忆(没背板子...),调了好久好久,过了样例, ...

  10. 【简单算法】40.Fizz Buzz

    题目: 写一个程序,输出从 到 n 数字的字符串表示. . 如果 n 是3的倍数,输出“Fizz”: . 如果 n 是5的倍数,输出“Buzz”: .如果 n 同时是3和5的倍数,输出 “FizzBu ...