python 实现二叉树相关算法
一、构建与遍历二叉树
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 实现二叉树相关算法的更多相关文章
- 二叉树-你必须要懂!(二叉树相关算法实现-iOS)
这几天详细了解了下二叉树的相关算法,原因是看了唐boy的一篇博客(你会翻转二叉树吗?),还有一篇关于百度的校园招聘面试经历,深刻体会到二叉树的重要性.于是乎,从网上收集并整理了一些关于二叉树的资料,及 ...
- python实现二叉树遍历算法
说起二叉树的遍历,大学里讲的是递归算法,大多数人首先想到也是递归算法.但作为一个有理想有追求的程序员.也应该学学非递归算法实现二叉树遍历.二叉树的非递归算法需要用到辅助栈,算法着实巧妙,令人脑洞大开. ...
- 数据结构-二叉搜索树和二叉树排序算法(python实现)
今天我们要介绍的是一种特殊的二叉树--二叉搜索树,同时我们也会讲到一种排序算法--二叉树排序算法.这两者之间有什么联系呢,我们一起来看一下吧. 开始之前呢,我们先来介绍一下如何创建一颗二叉搜索树. 假 ...
- [0x00 用Python讲解数据结构与算法] 概览
自从工作后就没什么时间更新博客了,最近抽空学了点Python,觉得Python真的是很强大呀.想来在大学中没有学好数据结构和算法,自己的意志力一直不够坚定,这次想好好看一本书,认真把基本的数据结构和算 ...
- Python实现各种排序算法的代码示例总结
Python实现各种排序算法的代码示例总结 作者:Donald Knuth 字体:[增加 减小] 类型:转载 时间:2015-12-11我要评论 这篇文章主要介绍了Python实现各种排序算法的代码示 ...
- NLP︱高级词向量表达(一)——GloVe(理论、相关测评结果、R&python实现、相关应用)
有很多改进版的word2vec,但是目前还是word2vec最流行,但是Glove也有很多在提及,笔者在自己实验的时候,发现Glove也还是有很多优点以及可以深入研究对比的地方的,所以对其进行了一定的 ...
- 用Python实现随机森林算法,深度学习
用Python实现随机森林算法,深度学习 拥有高方差使得决策树(secision tress)在处理特定训练数据集时其结果显得相对脆弱.bagging(bootstrap aggregating 的缩 ...
- Python面对对象相关知识总结
很有一段时间没使用python了,前两天研究微信公众号使用了下python的django服务,感觉好多知识都遗忘了,毕竟之前没有深入的实践,长期不使用就忘得快.本博的主要目的就是对Python中我认为 ...
- PAT甲级 二叉树 相关题_C++题解
二叉树 PAT (Advanced Level) Practice 二叉树 相关题 目录 <算法笔记> 重点摘要 1020 Tree Traversals (25) 1086 Tree T ...
随机推荐
- 在临床医学里面,bid、tid、qid和q3w是什么意思啊??这些缩写的全称是怎么写呢??
{ value: 'QD', name: 'QD 每日一次' }, { value: 'BID', name: 'BID 每日两次' }, { value: 'TID', name: 'TID 每日三 ...
- 第70天:jQuery基本选择器(一)
一.jQuery基本选择器 jQuery是javascript的一个库,包含多个可重用的函数,用来辅助我们简化javascript开发 jQuery能做的javascipt都能做到,而javascri ...
- deep learning2
九.Deep learning的常用模型或者方法 9.1.AutoEncoder自动编码器 Deep Learning最简单的一种方法是利用人工神经网络的特点,人工神经网络(ANN)本身就是具有层次结 ...
- BZOJ 1406 密码箱(数论)
很简洁的题目.求出x^2%n=1的所有x<=n的值. n<=2e9. 直接枚举x一定是超时的. 看看能不能化成有性质的式子. 有 (x+1)(x-1)%n==0,设n=a*b,那么一定有x ...
- 具体数学数论章-----致敬Kunth
整除性(divisible): 引入了代表整除性. m\n (m|n) 表示m整除n.注意这里的整除.表示的是n = km(k为整数). 在整除性这里.m必须是个正数.也许你可以描述n 是 m 的k倍 ...
- [TJOI2013]最长上升子序列 平衡树
其实是一道性质题. 首先观察到插入的数是递增的, 那么根据上升子序列的性质, 我们的非法情况就是统计到了在一个数前面的后插入的数, 但是由于插入的数是递增的,显然插入这个数后,这个数就是最大的,所以除 ...
- 无序数组中第Kth大的数
题目:找出无序数组中第Kth大的数,如{63,45,33,21},第2大的数45. 输入: 第一行输入无序数组,第二行输入K值. 该是内推滴滴打车时(2017.8.26)的第二题,也是<剑指of ...
- ContestHunter暑假欢乐赛 SRM 15
菜菜给题解,良心出题人!但我还是照常写SRM一句话题解吧... T1经典题正解好像是贪心...我比较蠢写了个DP,不过还跑的挺快的 f[i]=min( f[j-a[j]-1] )+1 { j+a[j ...
- 2-SAT入门
大概学了一下2-SAT,写了一道模板和一道USACO 输出一个方案的话,tarjan缩点后倒着拓扑,染色输出. 求任何解下选哪个就得枚举每个点dfs来判断选哪个. HIT 1917(2-sat模板) ...
- 将Visual Studio项目转换为Dot Net Core项目 csproj to xproj
删除csproj文件. 将 package.config 重命名为 project.json . 转换文件,将xml转换为json格式. <?xml version="1.0" ...