数据结构-树以及深度、广度优先遍历(递归和非递归,python实现)
前面我们介绍了队列、堆栈、链表,你亲自动手实践了吗?今天我们来到了树的部分,树在数据结构中是非常重要的一部分,树的应用有很多很多,树的种类也有很多很多,今天我们就先来创建一个普通的树。其他各种各样的树将来我将会一一为大家介绍,记得关注我的文章哦~
首先,树的形状就是类似这个样子的:

它最顶上面的点叫做树的根节点,一棵树也只能有一个根节点,在节点下面可以有多个子节点,子节点的数量,我们这里不做要求,而没有子节点的节点叫做叶子节点。
好,关于树的基本概念就介绍到这里了,话多千遍不如动手做一遍,接下来我们边做边学,我们来创建一棵树:
树
# 定义一个普通的树类
class Tree:
def __init__(self, data):
self.data = data
self.children = []
def get(self):
return self.data
def set(self):
return self.data
def addChild(self, child):
self.children.append(child)
def getChildren(self):
return self.children
这就是我们定义好的树类了,并给树添加了三个方法,分别是获取节点数据、设置节点数据、添加子节点、获取子节点。
这里的树类其实是一个节点类,很多个这样的节点可以构成一棵树,而我们就用根节点来代表这颗树。
接下来我们实例化一棵树:
# 初始化一个树
tree = Tree(0)
# 添加三个子节点
tree.addChild(Tree(1))
tree.addChild(Tree(2))
tree.addChild(Tree(3))
children = tree.getChildren()
# 每个子节点添加两个子节点
children[0].addChild(Tree(4))
children[0].addChild(Tree(5))
children[1].addChild(Tree(6))
children[1].addChild(Tree(7))
children[2].addChild(Tree(8))
children[2].addChild(Tree(9))
我们实例化好的树大概是这个样子的:

OK,我们的树已经实例化好了,我们先来对它分别采用递归和非递归的方式进行广度优先遍历:
广度优先遍历
广度优先遍历,就是从上往下,一层一层从左到右对树进行遍历。
在用非递归方式进行广度优先遍历的时候,我们需要用到前面介绍过的队列类型,所以我们来定义一个队列类:
# 用以实现广度优先遍历
class Queue():
def __init__(self):
self.__list = list()
def isEmpty(self):
return self.__list == []
def push(self, data):
self.__list.append(data)
def pop(self):
if self.isEmpty():
return False
return self.__list.pop(0)
用队列实现广度优先遍历
利用队列我们只要在节点出队的时候让该节点的子节点入队即可。
# 广度优先遍历
def breadthFirst(tree):
queue = Queue()
queue.push(tree)
result = []
while not queue.isEmpty():
node = queue.pop()
result.append(node.data)
for c in node.getChildren():
queue.push(c)
return result
调用一下:
print(breadthFirst(tree))
输出:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
递归实现广度优先遍历
# 递归方式实现广度优先遍历
def breadthFirstByRecursion(gen, index=0, nextGen=[], result=[]):
if type(gen) == Tree:
gen = [gen]
result.append(gen[index].data)
children = gen[index].getChildren()
nextGen += children
if index == len(gen)-1:
if nextGen == []:
return
else:
gen = nextGen
nextGen = []
index = 0
else:
index += 1
breadthFirstByRecursion(gen, index, nextGen,result)
return result
调用一下:
print(breadthFirstByRecursion(tree))
输出:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
深度优先遍历
深度优先遍历,就是从上往下,从左到右,先遍历节点的子节点再遍历节点的兄弟节点。
采用非递归方式实现深度优先遍历呢,我们需要用到前面介绍过的堆栈结构,所以我们现在定义一个堆栈类吧:
# 用以实现深度优先遍历
class Stack():
def __init__(self):
self.__list = list()
def isEmpty(self):
return self.__list == []
def push(self, data):
self.__list.append(data)
def pop(self):
if self.isEmpty():
return False
return self.__list.pop()
利用堆栈实现深度优先遍历
实现深度优先遍历,我们只要在节点出栈的时候把该节点的子节点从左到右压入堆栈即可。
# 深度优先遍历
def depthFirst(tree):
stack = Stack()
stack.push(tree)
result = []
while not stack.isEmpty():
node = stack.pop()
result.append(node.data)
children = node.getChildren()
children = reversed(children)
for c in children:
stack.push(c)
return result
调用一下:
# 深度优先遍历
print(depthFirst(tree))
输出:[0, 1, 4, 5, 2, 6, 7, 3, 8, 9]
递归实现深度优先遍历
# 递归方式实现深度优先遍历
def depthFirstByRecursion(tree, result=[]):
result.append(tree.data)
children = tree.getChildren()
for c in children:
depthFirstByRecursion(c, result)
return result
调用一下:
print(depthFirstByRecursion(tree))
输出:[0, 1, 4, 5, 2, 6, 7, 3, 8, 9]
好啦,今天我们的树就介绍到这里了,对于广度优先遍历的递归实现,你有更好的方法吗?请留言告诉我吧。
数据结构-树以及深度、广度优先遍历(递归和非递归,python实现)的更多相关文章
- 数据结构二叉树的递归与非递归遍历之java,javascript,php实现可编译(1)java
前一段时间,学习数据结构的各种算法,概念不难理解,只是被C++的指针给弄的犯糊涂,于是用java,web,javascript,分别去实现数据结构的各种算法. 二叉树的遍历,本分享只是以二叉树中的先序 ...
- 数据结构作业——图的存储及遍历(邻接矩阵、邻接表+DFS递归、非递归+BFS)
邻接矩阵存图 /* * @Author: WZY * @School: HPU * @Date: 2018-11-02 18:35:27 * @Last Modified by: WZY * @Las ...
- Java实现二叉树的先序、中序、后序、层序遍历(递归和非递归)
二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的.对于二叉树,有前序.中序以及后序三种遍历方法.因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易 ...
- C实现二叉树(模块化集成,遍历的递归与非递归实现)
C实现二叉树模块化集成 实验源码介绍(源代码的总体介绍):header.h : 头文件链栈,循环队列,二叉树的结构声明和相关函数的声明.LinkStack.c : 链栈的相关操作函数定义.Queue. ...
- 二叉树的创建、遍历(递归和非递归实现)、交换左右子数、求高度(c++实现)
要求:以左右孩子表示法实现链式方式存储的二叉树(lson—rson),以菜单方式设计并完成功能任务:建立并存储树.输出前序遍历结果.输出中序遍历结果.输出后序遍历结果.交换左右子树.统计高度,其中对于 ...
- 二叉树之AVL树的平衡实现(递归与非递归)
这篇文章用来复习AVL的平衡操作,分别会介绍其旋转操作的递归与非递归实现,但是最终带有插入示例的版本会以递归呈现. 下面这张图绘制了需要旋转操作的8种情况.(我要给做这张图的兄弟一个赞)后面会给出这八 ...
- 二叉树3种递归和非递归遍历(Java)
import java.util.Stack; //二叉树3种递归和非递归遍历(Java) public class Traverse { /******************一二进制树的定义*** ...
- 二叉树前中后/层次遍历的递归与非递归形式(c++)
/* 二叉树前中后/层次遍历的递归与非递归形式 */ //*************** void preOrder1(BinaryTreeNode* pRoot) { if(pRoot==NULL) ...
- JAVA递归、非递归遍历二叉树(转)
原文链接: JAVA递归.非递归遍历二叉树 import java.util.Stack; import java.util.HashMap; public class BinTree { priva ...
随机推荐
- Win8 Metro(C#)数字图像处理--2.67图像最大值滤波器
原文:Win8 Metro(C#)数字图像处理--2.67图像最大值滤波器 [函数名称] 最大值滤波器WriteableBitmap MaxFilterProcess(WriteableBi ...
- iOS学习总结之ARC和非ARC的单例模式实现
iOS单例模式的实现 首先我们要明白下面三个问题: 什么是单例模式 单例模式的优点 如何实现单例模式 1.什么是单例模式 单例模式(Singleton):单例模式确保对于一个给定的类只有一个实例存在, ...
- PHP XDebug Sublime Text 单步调试
前置环境:已经安装好LNMP 1. 安装xdebug 可以通过pear包管理来安装 sudo apt-get install php-pear sudo pecl install xdebug 这里我 ...
- 超详细SQL SERVER 2016跨网段和局域网发布订阅配置图解和常见问题
原文:超详细SQL SERVER 2016跨网段和局域网发布订阅配置图解和常见问题 转载标明出处:http://blog.csdn.net/u012861467 前方高能,要有点耐心,图片较多,注意在 ...
- SQL Server 2017 SELECT…INTO 创建的新表指定到文件组
原文:SQL Server 2017 SELECT-INTO 创建的新表指定到文件组 SELECT-INTO 在 SQL Server 中也是常见的一个功能,过去用此方法创建的新表只能存储到默认的文件 ...
- 【码云周刊第 32 期】程序员眼中的 Vue 与 Angular !
码云项目推荐 基于 Vue 的项目: 1.项目名称:基于 Vue.js 的 UI 组件库 项目简介:iView 是一套基于 Vue.js 的 UI 组件库,主要服务于 PC 界面的中后台产品. 项目地 ...
- ARTS 12.31 - 1.4
Algorithm 这是一道需要用动态规划的问题.求字符串的最长回文子序列. 复习了一遍动态规划,重点是要分析出最优解所包含的子问题的最优解,把过程描述为数学公式. 题目https://leetcod ...
- 【转】编程之道 之 Rob Pike
1.你无法断定程序会在什么地方耗费运行时间.瓶颈经常出现在想不到的地方,所以别急于胡乱找个地方改代码,除非你已经证实那儿就是瓶颈所在. 2.估量.在你没对代码进行估量,特别是没找到最耗时的那部分之前, ...
- 零元学Expression Blend 4 - Chapter 34 啊~!!我不要毛毛的感觉!-使用布局修整「UseLayoutRounding」
原文:零元学Expression Blend 4 - Chapter 34 啊~!!我不要毛毛的感觉!-使用布局修整「UseLayoutRounding」 本章将介绍UseLayoutRounding ...
- shell脚本配置ssh免密登陆
通过shell脚本配置免密登陆,分为两个脚本,一个是配置文件config.env,一个是正式脚本sshkey.sh. # config.envexport HOST_USER=(root) expor ...