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 ...
随机推荐
- 关于houghlines函数角度问题的说明
以上是opecv reference里面的说明. Image必须是8位单通道图(可以使灰度图.二值图.边缘图等) Rho:距离分辨率,一般为1 Theta:角度分辨率,一般为CV_PI/180 Thr ...
- tc:逼良为娼
tc的学习原来是想着直接从用户态学习的,但是万万没想到哇,qdisc class两个概念直接把我给搞晕了,直接看代码吧 调用:tc qdisc add dev tap0 root handle 1: ...
- asp.net 间隔一段时间执行某方法
设想网站后台每秒自动更新一下Cache["test"]中的值,通过这个实现就可以完成一些在间隔多少时间更新一下数据库的操作. 1.定义一个事件类BMAEvent,在Processo ...
- Go语言【第八篇】:Go语言变量作用域
Go语言变量作用域 作用域为已声明标识符所表示的常量.类型.变量.函数或包在源代码中的作用范围,Go语言中变量可以在三个地方声明: 函数内定义的变量称为局部变量: 函数外定义的变量称为全局变量: 函数 ...
- 【题解】51nod 1672区间交
二分答案 + two - pointer + 树状数组大法好ヽ(゚∀゚)メ(゚∀゚)ノ 我们可以直接二分一个答案,然后检验 是否存在一个值大于等于这个二分的答案的,且覆盖次数大于等于 \(k\) 的区 ...
- Leetcode中单链表题总结
以下是个人对所做过的LeetCode题中有关链表类型题的总结,博主小白啊,若有错误的地方,请留言指出,谢谢. 一.有关反转链表 反转链表是在单链表题中占很大的比例,有时候,会以各种形式出现在题中,是比 ...
- BZOJ1022 [SHOI2008]小约翰的游戏John 【博弈论】
1022: [SHOI2008]小约翰的游戏John Time Limit: 1 Sec Memory Limit: 162 MB Submit: 3014 Solved: 1914 [Submi ...
- HDOJ(HDU).1003 Max Sum (DP)
HDOJ(HDU).1003 Max Sum (DP) 点我挑战题目 算法学习-–动态规划初探 题意分析 给出一段数字序列,求出最大连续子段和.典型的动态规划问题. 用数组a表示存储的数字序列,sum ...
- HDU 1002 (高精度加法运算)
A + B ProblemII Time Limit: 2000/1000 MS(Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...
- 将Visual Studio项目转换为Dot Net Core项目 csproj to xproj
删除csproj文件. 将 package.config 重命名为 project.json . 转换文件,将xml转换为json格式. <?xml version="1.0" ...