树表示由边连接的节点。它是一个非线性的数据结构。它具有以下特性。

  1. 一个节点被标记为根节点。
  2. 除根节点之外的每个节点都与一个父节点关联。
  3. 每个节点可以有一个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树遍历算法

遍历是一个访问树的所有节点的过程,也可以打印它们的值。因为,所有节点都是通过边(链接)连接的,所以我们总是从根(头)节点开始。也就是说,我们不能随机访问树中的节点。我们走过一棵树有三种方法

  1. 先序遍历
  2. 中序遍历
  3. 后序遍历

顺序遍历

在这个遍历方法中,首先访问左子树,然后访问根,然后访问右子树。我们应该始终记住,每个节点都可以表示子树本身。
在下面的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 -二叉树 创建与遍历算法(很详细)的更多相关文章

  1. leadcode的Hot100系列--二叉树创建和遍历

    很多题目涉及到二叉树,所以先把二叉树的一些基本的创建和遍历写一下,方便之后的本地代码调试. 为了方便,这里使用的数据为char类型数值,初始化数据使用一个数组. 因为这些东西比较简单,这里就不做过多详 ...

  2. 二叉树 ADT接口 遍历算法 常规运算

    BTree.h   (结构定义, 基本操作, 遍历) #define MS 10 typedef struct BTreeNode{ char data; struct BTreeNode * lef ...

  3. Go语言二叉树定义及遍历算法实现

    // binary_tree 二叉树 package Algorithm import ( "reflect" ) // 二叉树定义 type BinaryTree struct ...

  4. python二叉树的深度遍历之先序遍历流程图

  5. [LintCode] Binary Tree Level Order Traversal(二叉树的层次遍历)

    描述 给出一棵二叉树,返回其节点值的层次遍历(逐层从左往右访问) 样例 给一棵二叉树 {3,9,20,#,#,15,7} : 3 / \ 9 20 / \ 15 7 返回他的分层遍历结果: [ [3] ...

  6. 【算法编程 C++ Python】根据前序遍历、中序遍历重建二叉树

    题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7, ...

  7. python聚类算法实战详细笔记 (python3.6+(win10、Linux))

    python聚类算法实战详细笔记 (python3.6+(win10.Linux)) 一.基本概念:     1.计算TF-DIF TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库 ...

  8. 算法:二叉树的层次遍历(递归实现+非递归实现,lua)

    二叉树知识参考:深入学习二叉树(一) 二叉树基础 递归实现层次遍历算法参考:[面经]用递归方法对二叉树进行层次遍历 && 二叉树深度 上面第一篇基础写得不错,不了解二叉树的值得一看. ...

  9. python二叉树递归算法之后序遍历,前序遍历,中序遍历

    #!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2016-11-18 08:53:45 # @Author : why_not_try ...

随机推荐

  1. python的socket模块

    sk.bind(address) s.bind(address) 将套接字绑定到地址.address地址的格式取决于地址族.在AF_INET下,以元组(host,port)的形式表示地址. sk.li ...

  2. Envoy 源码分析--LDS

    Envoy 源码分析--LDS LDS 是 Envoy 用来自动获取 listener 的 API. Envoy 通过 API 可以增加.修改或删除 listener. 先来总结下 listener ...

  3. C#中的Contains与IndexOf的区别

     C#中要判断一个字符串是否包含另一个字符串,常用的两种方法是 str.Contains和str.IndexOf 这两个方法的区别是: Contains是找指定字符串是否包含一个字串,返回值的bo ...

  4. 【iOS】UILabel 常用属性设置

    UILabel 的一些常用属性,示例代码如下: // 字体大小 label.font = [UIFont systemFontOfSize:14.0]; label.font = [UIFont fo ...

  5. codeforces 327 B. Hungry Sequence

    题目链接 题目就是让你输出n个数的序列,要保证该序列是递增的,并且第i个数的前面不能保护它的约数,我直接先对前100000的素数打表,然后输出前n个,so easy. //cf 191 B #incl ...

  6. ipad pro 为什么不行

    TalkingData公布的数据显示,iPad Pro在中国发行首月的销量仅为49 300台,而此前iPad Air 2发行首月后销量曾高达55.7万台.那么到底是什么原因,让这个被寄予厚望的iPad ...

  7. 记录一下我做Udacity 的Data Scientist Nano Degree Project

    做项目的时候看了别人的blog,决定自己也随手记录下在做项目中遇到的好的小知识点. 最近在做Udacity的Data Scientist Nano Degree Project的Customer_Se ...

  8. ibatis 核心原理解析

    最近查找一个生产问题的原因,需要深入研究 ibatis 框架的源码.虽然最后证明问题的原因与 ibatis 无关,但是这个过程加深了对 ibatis 框架原理的理解. 这篇文章主要就来讲讲 ibati ...

  9. 【POJ - 2385】Apple Catching(动态规划)

    Apple Catching 直接翻译了 Descriptions 有两棵APP树,编号为1,2.每一秒,这两棵APP树中的其中一棵会掉一个APP.每一秒,你可以选择在当前APP树下接APP,或者迅速 ...

  10. linux安装启动mongodb

    1:下载 http://www.mongodb.org/downloads 在85机器上上传压缩包后解压缩. 首先在linux中解压缩安装程序 通过命令操作: 解压 tar -zxvf mongodb ...