前面我们介绍了队列、堆栈、链表,你亲自动手实践了吗?今天我们来到了树的部分,树在数据结构中是非常重要的一部分,树的应用有很多很多,树的种类也有很多很多,今天我们就先来创建一个普通的树。其他各种各样的树将来我将会一一为大家介绍,记得关注我的文章哦~

首先,树的形状就是类似这个样子的:

它最顶上面的点叫做树的根节点,一棵树也只能有一个根节点,在节点下面可以有多个子节点,子节点的数量,我们这里不做要求,而没有子节点的节点叫做叶子节点。

好,关于树的基本概念就介绍到这里了,话多千遍不如动手做一遍,接下来我们边做边学,我们来创建一棵树:

# 定义一个普通的树类
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实现)的更多相关文章

  1. 数据结构二叉树的递归与非递归遍历之java,javascript,php实现可编译(1)java

    前一段时间,学习数据结构的各种算法,概念不难理解,只是被C++的指针给弄的犯糊涂,于是用java,web,javascript,分别去实现数据结构的各种算法. 二叉树的遍历,本分享只是以二叉树中的先序 ...

  2. 数据结构作业——图的存储及遍历(邻接矩阵、邻接表+DFS递归、非递归+BFS)

    邻接矩阵存图 /* * @Author: WZY * @School: HPU * @Date: 2018-11-02 18:35:27 * @Last Modified by: WZY * @Las ...

  3. Java实现二叉树的先序、中序、后序、层序遍历(递归和非递归)

    二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的.对于二叉树,有前序.中序以及后序三种遍历方法.因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易 ...

  4. C实现二叉树(模块化集成,遍历的递归与非递归实现)

    C实现二叉树模块化集成 实验源码介绍(源代码的总体介绍):header.h : 头文件链栈,循环队列,二叉树的结构声明和相关函数的声明.LinkStack.c : 链栈的相关操作函数定义.Queue. ...

  5. 二叉树的创建、遍历(递归和非递归实现)、交换左右子数、求高度(c++实现)

    要求:以左右孩子表示法实现链式方式存储的二叉树(lson—rson),以菜单方式设计并完成功能任务:建立并存储树.输出前序遍历结果.输出中序遍历结果.输出后序遍历结果.交换左右子树.统计高度,其中对于 ...

  6. 二叉树之AVL树的平衡实现(递归与非递归)

    这篇文章用来复习AVL的平衡操作,分别会介绍其旋转操作的递归与非递归实现,但是最终带有插入示例的版本会以递归呈现. 下面这张图绘制了需要旋转操作的8种情况.(我要给做这张图的兄弟一个赞)后面会给出这八 ...

  7. 二叉树3种递归和非递归遍历(Java)

    import java.util.Stack; //二叉树3种递归和非递归遍历(Java) public class Traverse { /******************一二进制树的定义*** ...

  8. 二叉树前中后/层次遍历的递归与非递归形式(c++)

    /* 二叉树前中后/层次遍历的递归与非递归形式 */ //*************** void preOrder1(BinaryTreeNode* pRoot) { if(pRoot==NULL) ...

  9. JAVA递归、非递归遍历二叉树(转)

    原文链接: JAVA递归.非递归遍历二叉树 import java.util.Stack; import java.util.HashMap; public class BinTree { priva ...

随机推荐

  1. Qt for windows消息循环、libqxt分析和wince快捷键处理

    Qt for windows消息循环.libqxt分析和wince快捷键处理 利用Qt做windows图形界面开发和MFC相比,个人感觉还是比较简单好用的:首先利用Designer工具搞个ui文件:然 ...

  2. intellij开发安卓与genymotion配合

    原文:intellij开发安卓与genymotion配合 [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http: ...

  3. Android零基础入门第77节:Activity任务栈和启动模式

    通过前面的学习,Activity的基本使用都已掌握,接下来一起来学习更高级的一些内容. Android采用任务栈(Task)的方式来管理Activity的实例.当启动一个应用时,Android就会为之 ...

  4. UWP开发-自适应布局

    了解css的人知道,对于不同的屏幕尺寸,css使用一种名为媒体查询的东东来适用不同的屏幕尺寸,以提升用户体验.当用户使用PC等大屏幕的设备时,网页将呈现一种布局形式:而当用户使用手机等小屏幕设备时,布 ...

  5. BI-学习之 新概念介绍

    什么是统一维度模型 层次结构.级别.成员和度量值 什么是MDX MDX与SQL的区别 什么是数据仓库 什么是OLAP数据分析引擎 BI企业级解决方案 什么是统一维度模型 维度(dimension)是描 ...

  6. 第一式、单例模式-Singleton模式(创建型)

    一.简介 单例模式主要用的作用是用于保证程序运行中某个类只有一个实例,并提供一个全局入口点.单例模式(Singleton)为GOF阐述的标准24种设计模式中最简单的一个.但随着时间推移,GOF所阐述的 ...

  7. .net core 2.0 dbfirst 报 dotnet ef 未找到与命令“dotnet-ef”匹配的可执行文件的解决办法

    问题描述: 最近研究了一段时间.netcore dbfirst,新建类库用来生成实体模型,执行命令总是提示 未找到与命令“dotnet-ef”匹配的可执行文件,根据网上的解决办法引用 Microsof ...

  8. 自己动手写jQuery插件---Tip(提示框)

    对jQuery相信很多同学和我一样平时都是拿来主义,没办法,要怪只能怪jQuery太火了,各种插件基本能满足平时的要求.但是这毕竟不是长久之道,古人云:“授之以鱼,不如授之以渔”. 为了方便之前没有接 ...

  9. C语言实现常用数据结构——队列

    #include<stdio.h> #include<stdlib.h> #define MAX_SIZE 10 /* 用一个动态数组来实现队列 */ typedef stru ...

  10. 安装metasploitable3的经验总结

    一个月没有写学习记录了,但是这一个月一直没闲着,抽空写写自己装metasploitable3的经验教训(提示:只要你的环境配置没错,步骤没错,多试几次就会成功了,我总共测试了15次,,短的耗时30分钟 ...