一、构建与遍历二叉树

基本性质
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. 制作QQ微信支付宝三合一收款码

    转载:http://blog.mambaxin.com/article/56 发现很多博客都带了打赏功能,虽说打赏的人可能很少,但始终是一份心意,能让博主知道自己写的文章有用,能够帮助到人.所以,我也 ...

  2. springMVC视图有哪些?-009

    html,json,pdf等. springMVC 使用ViewResolver来根据controller中返回的view名关联到具体的view对象. 使用view对象渲染返回值以生成最终的视图,比如 ...

  3. 织梦CMS建站入门学习(二)

    织梦建站的数据库设计: 1.模型表:根据网站的需求,建立不同的数据模型,如:文章浏览,软件下载,视频观看等等. 2.栏目表:根据网站的需求,建立不同的栏目,每一个栏目选择一个数据模型. 3.内容主表: ...

  4. MYsql 数据库密码忘记(Window)-2(mysql 5.7)

    很久没用Mysql了,再次打开,发现用不了了,密码忘了,服务也无法打开,在cmd中输入mysql之后,显示不是内部指令. 看来问题是mysql服务打不开了 (1)在cmd中 输入net start m ...

  5. [C/C++] C/C++错题集

    1. 解析: A:在GCC下输出:0    在VC6.0下输出:1 B:在GCC下输出:段错误 (核心已转储)    在VC6.0下输出:已停止工作,出现了一个问题,导致程序停止正常工作. C:正常 ...

  6. css样式 一定要reset?

    有大神讲过了,直接看http://www.zhangxinxu.com/wordpress/?p=758

  7. BZOJ4804 欧拉心算(莫比乌斯反演+欧拉函数+线性筛)

    一通套路后得Σφ(d)μ(D/d)⌊n/D⌋2.显然整除分块,问题在于怎么快速计算φ和μ的狄利克雷卷积.积性函数的卷积还是积性函数,那么线性筛即可.因为μ(pc)=0 (c>=2),所以f(pc ...

  8. hdu 1392 Surround the Trees (凸包)

    Surround the Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  9. [NOI2001]炮兵阵地 状压DP

    题面: 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图.在每一格平原地形上最多 ...

  10. 【BZOJ4894】天赋(矩阵树定理)

    [BZOJ4894]天赋(矩阵树定理) 题面 BZOJ Description 小明有许多潜在的天赋,他希望学习这些天赋来变得更强.正如许多游戏中一样,小明也有n种潜在的天赋,但有 一些天赋必须是要有 ...