Python -二叉树 创建与遍历算法(很详细)
树表示由边连接的节点。它是一个非线性的数据结构。它具有以下特性。
- 一个节点被标记为根节点。
- 除根节点之外的每个节点都与一个父节点关联。
- 每个节点可以有一个arbiatry编号的chid节点。
我们使用前面讨论的os节点概念在python中创建了一个树数据结构。我们将一个节点指定为根节点,然后将更多的节点添加为子节点。下面是创建根节点的程序。
创建树
创建根
我们只需要创建一个节点类并向节点添加赋值。这就变成了只有根节点的树。
class Node:
def __init__(self, data):
self.left = None #左节点
self.right = None #右节点
self.data = data #值
def PrintTree(self):
print(self.data)
root = Node(10) #创建节点
root.PrintTree()
当执行上述代码时,将产生以下结果-
10
插入到树中
要插入到树中,我们使用上面创建的相同节点类,并向其添加一个插入类。insert类将节点的值与父节点的值进行比较,并决定将其添加为左节点或右节点。最后,PrintTree类用于打印树。
class Node:
def __init__(self, data):
self.left = None
self.right = None
self.data = data def insert(self, data):
# 将新值与父节点进行比较
if self.data: # 非空
if data < self.data: #新值较小,放左边
if self.left is None: #若空,则新建插入节点
self.left = Node(data)
else: #否则,递归往下查找
self.left.insert(data)
elif data > self.data: #新值较大,放右边
if self.right is None: #若空,则新建插入节点
self.right = Node(data)
else: #否则,递归往下查找
self.right.insert(data)
else:
self.data = data # 打印这棵树,中序遍历
def PrintTree(self):
if self.left:
self.left.PrintTree()
print( self.data),
if self.right:
self.right.PrintTree() # 使用insert方法添加节点
root = Node(12)
root.insert(6)
root.insert(14)
root.insert(3) root.PrintTree()
当执行上述代码时,将产生以下结果-
3 6 12 14
遍历树
可以通过决定访问每个节点的序列来遍历树。我们可以清楚地看到,我们可以从一个节点开始,然后首先访问左子树,然后访问右子树。或者我们也可以先访问右子树然后访问左子树。因此,这些树遍历方法有不同的名称。我们将在实现树遍历算法的章节中详细研究它们。
Python树遍历算法
遍历是一个访问树的所有节点的过程,也可以打印它们的值。因为,所有节点都是通过边(链接)连接的,所以我们总是从根(头)节点开始。也就是说,我们不能随机访问树中的节点。我们走过一棵树有三种方法
- 先序遍历
- 中序遍历
- 后序遍历
顺序遍历
在这个遍历方法中,首先访问左子树,然后访问根,然后访问右子树。我们应该始终记住,每个节点都可以表示子树本身。
在下面的python程序中,我们使用Node类为根节点以及左右节点创建位置占位符。然后我们创建一个insert函数来向树中添加数据。最后,通过创建一个空列表并首先添加左节点,然后添加根节点或父节点来实现order遍历逻辑。最后添加左节点来完成order遍历。
class Node:
def __init__(self, data):
self.left = None
self.right = None
self.data = data
# Insert Node
def insert(self, data):
if self.data:
if data < self.data:
if self.left is None:
self.left = Node(data)
else:
self.left.insert(data)
elif data > self.data:
if self.right is None:
self.right = Node(data)
else:
self.right.insert(data)
else:
self.data = data
# Print the Tree
def PrintTree(self):
if self.left:
self.left.PrintTree()
print( self.data),
if self.right:
self.right.PrintTree()
# 中序遍历
# Left -> Root -> Right
def inorderTraversal(self, root):
res = []
if root:
res = self.inorderTraversal(root.left)
res.append(root.data)
res = res + self.inorderTraversal(root.right)
return res
root = Node(27)
root.insert(14)
root.insert(35)
root.insert(10)
root.insert(19)
root.insert(31)
root.insert(42)
print(root.inorderTraversal(root))
当执行上述代码时,将产生以下结果-
[10、14、19、27、31、35、42]
预购遍历
在这种遍历方法中,首先访问根节点,然后访问左子树,最后访问右子树。
在下面的python程序中,我们使用Node类为根节点以及左右节点创建位置占位符。然后我们创建一个insert函数来向树中添加数据。最后,通过创建一个空列表并首先添加根节点,然后添加左节点来实现预排序遍历逻辑。最后添加正确的节点来完成预定遍历。请注意,此过程对每个子树重复,直到所有t
class Node:
def __init__(self, data):
self.left = None
self.right = None
self.data = data
# Insert Node
def insert(self, data):
if self.data:
if data < self.data:
if self.left is None:
self.left = Node(data)
else:
self.left.insert(data)
elif data > self.data:
if self.right is None:
self.right = Node(data)
else:
self.right.insert(data)
else:
self.data = data
# Print the Tree
def PrintTree(self):
if self.left:
self.left.PrintTree()
print( self.data),
if self.right:
self.right.PrintTree()
# 先序遍历
# Root -> Left ->Right
def PreorderTraversal(self, root):
res = []
if root:
res.append(root.data)
res = res + self.PreorderTraversal(root.left)
res = res + self.PreorderTraversal(root.right)
return res
root = Node(27)
root.insert(14)
root.insert(35)
root.insert(10)
root.insert(19)
root.insert(31)
root.insert(42)
print(root.PreorderTraversal(root))
当执行上述代码时,将产生以下结果-
[27, 14, 10, 19, 35, 31, 42]
后序遍历
在这个遍历方法中,根节点最后访问,因此得名。首先遍历左子树,然后遍历右子树,最后遍历根节点。
在下面的python程序中,我们使用Node类为根节点以及左右节点创建位置占位符。然后我们创建一个insert函数来向树中添加数据。最后,通过创建一个空列表并先添加左节点后添加右节点来实现后序遍历逻辑。最后添加根节点或父节点来完成后序遍历。请注意,此过程将对每个子树重复,直到遍历所有节点。
class Node:
def __init__(self, data):
self.left = None
self.right = None
self.data = data
# Insert Node
def insert(self, data):
if self.data:
if data < self.data:
if self.left is None:
self.left = Node(data)
else:
self.left.insert(data)
elif data > self.data:
if self.right is None:
self.right = Node(data)
else:
self.right.insert(data)
else:
self.data = data
# Print the Tree
def PrintTree(self):
if self.left:
self.left.PrintTree()
print( self.data),
if self.right:
self.right.PrintTree()
# 后序遍历
# Left ->Right -> Root
def PostorderTraversal(self, root):
res = []
if root:
res = self.PostorderTraversal(root.left)
res = res + self.PostorderTraversal(root.right)
res.append(root.data)
return res
root = Node(27)
root.insert(14)
root.insert(35)
root.insert(10)
root.insert(19)
root.insert(31)
root.insert(42)
print(root.PostorderTraversal(root))
当执行上述代码时,将产生以下结果-
[10、19、14、31、42、35、27]
Python -二叉树 创建与遍历算法(很详细)的更多相关文章
- leadcode的Hot100系列--二叉树创建和遍历
很多题目涉及到二叉树,所以先把二叉树的一些基本的创建和遍历写一下,方便之后的本地代码调试. 为了方便,这里使用的数据为char类型数值,初始化数据使用一个数组. 因为这些东西比较简单,这里就不做过多详 ...
- 二叉树 ADT接口 遍历算法 常规运算
BTree.h (结构定义, 基本操作, 遍历) #define MS 10 typedef struct BTreeNode{ char data; struct BTreeNode * lef ...
- Go语言二叉树定义及遍历算法实现
// binary_tree 二叉树 package Algorithm import ( "reflect" ) // 二叉树定义 type BinaryTree struct ...
- python二叉树的深度遍历之先序遍历流程图
- [LintCode] Binary Tree Level Order Traversal(二叉树的层次遍历)
描述 给出一棵二叉树,返回其节点值的层次遍历(逐层从左往右访问) 样例 给一棵二叉树 {3,9,20,#,#,15,7} : 3 / \ 9 20 / \ 15 7 返回他的分层遍历结果: [ [3] ...
- 【算法编程 C++ Python】根据前序遍历、中序遍历重建二叉树
题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7, ...
- python聚类算法实战详细笔记 (python3.6+(win10、Linux))
python聚类算法实战详细笔记 (python3.6+(win10.Linux)) 一.基本概念: 1.计算TF-DIF TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库 ...
- 算法:二叉树的层次遍历(递归实现+非递归实现,lua)
二叉树知识参考:深入学习二叉树(一) 二叉树基础 递归实现层次遍历算法参考:[面经]用递归方法对二叉树进行层次遍历 && 二叉树深度 上面第一篇基础写得不错,不了解二叉树的值得一看. ...
- python二叉树递归算法之后序遍历,前序遍历,中序遍历
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2016-11-18 08:53:45 # @Author : why_not_try ...
随机推荐
- [leetcode] 67. Add Binary (easy)
原题链接 思路: 用一个数保存进制,从后往前不断pop出两个数字和进制数相加,放入返回值中. var addBinary = function(a, b) { var arrA = a.split(' ...
- python-if条件判断与while/for循环
条件判断if 让计算机像人一样,能判断是非对错,根据条件做一些事情. if ''' ------ if代码结构:------- if 条件: 代码体 tips:同一缩进范围内的代码被视作同一代码体,p ...
- WGS84坐标与web墨卡托投影坐标转换
许久没有使用坐标转换,记忆有些模糊了,以后还是会用到,先将WGS84与web墨卡托转换复习一下: 1.84转web墨卡托 //核心公式 平面坐标x = 经度*20037508.34/108 平面坐标y ...
- ThinkPHP5.0 模板
ThinkPHP5.0 模板 模板渲染 默认的视图目录是默认的模块下的view目录 渲染规则:调用 \think\View 类fetch方法 // [模板文件目录]/当前控制器名(小写+下划线)/当前 ...
- Java之JDBC 通过加载properties配置文件连接数据库
通常情况下,我们通过JDBC连接数据库的时候,不会将数据库相关配置写死,因为到时候数据库一有改动,就要重新打包部署到服务器或者替换相关的.class文件,这样非常不灵活.因此,咱们一般会通过读取配置文 ...
- session对象和cookie对象的区别
1.cookie数据存放在客户的浏览器上,session数据放在服务器上2.cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session3.ses ...
- 努力做一个优秀的programmer [ C# 影院售票系统]
Cinema.cs类 [Serializable] // 电影院类 public class Cinema { public Cinema() { //二进制 SoldTickets = new Li ...
- Java8中的流操作-基本使用&性能测试
为获得更好的阅读体验,请访问原文:传送门 一.流(Stream)简介 流是 Java8 中 API 的新成员,它允许你以声明式的方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现).这有点儿 ...
- 【POJ - 3258】River Hopscotch(二分)
River Hopscotch 直接中文 Descriptions 每年奶牛们都要举办各种特殊版本的跳房子比赛,包括在河里从一块岩石跳到另一块岩石.这项激动人心的活动在一条长长的笔直河道中进行,在起点 ...
- C#连接SQL Anywhere 12 数据库
using System;using System.Data.Common; namespace ConsoleApplication27{ class Program { ...