上篇文章我们介绍了树的概念,今天我们来介绍一种特殊的树——二叉树,二叉树的应用很广,有很多特性。今天我们一一来为大家介绍。

二叉树

顾名思义,二叉树就是只有两个节点的树,两个节点分别为左节点和右节点,特别强调,即使只有一个子节点也要区分它是左节点还是右节点。

常见的二叉树有一般二叉树、完全二叉树、满二叉树、线索二叉树、霍夫曼树、二叉排序树、平衡二叉树、红黑树、B树这么多种类。我们这篇文章中简单介绍一般二叉树、完全二叉树和满二叉树。

一般二叉树

很简单,只要满足子节点数不超过两个的树就是一棵二叉树。长这样:

满二叉树

满二叉树在一般二叉树的基础上要求除了最后一层的节点之外,每一个节点都必须有两个子节点。

完全二叉树

完全二叉树要求从第一层到倒数第二层组成的树是一颗满二叉树,最后一层的节点要满足从左往右排列。

好,关于二叉树的概念,我们就介绍到这里,下面我们来介绍二叉树的前序、中序、后序遍历。

在此之前呢,我们先创建一颗二叉树:

class BinaryTree:
def __init__(self, data):
self.data = data
self.left = None
self.right = None def get(self):
return self.data def getLeft(self):
return self.left def getRight(self):
return self.right def setLeft(self, node):
self.left = node def setRight(self, node):
self.right = node

好,这里我们定义好了一个二叉树类,并给它添加了一下方法,然后我们来实例化一颗二叉树:

binaryTree = BinaryTree(0)
binaryTree.setLeft(BinaryTree(1))
binaryTree.setRight(BinaryTree(2))
binaryTree.getLeft().setLeft(BinaryTree(3))
binaryTree.getLeft().setRight(BinaryTree(4))
binaryTree.getRight().setLeft(BinaryTree(5))
binaryTree.getRight().setRight(BinaryTree(6))

实例化好的二叉树是长这个样子的:

前序遍历

接下来,我们对这棵树进行前序遍历。在此之前,我们介绍一下什么是前序遍历。

前面我们介绍过了树的深度优先遍历和广度优先遍历,这里就不再赘述了。

前序遍历的顺序就是先遍历树的父节点,然后遍历树的左节点,然后遍历树的右节点,以此类推。

对于我们上面定义好的二叉树来说,它的前序遍历结果就是:0 -> 1 -> 3 -> 4 -> 2 -> 5 -> 6

对于前序、中序、后序遍历来说,采用递归的方式是非常方便的。这里我们就用递归来实现一下:

def preorderTraversal(now, result=[]):
if now == None:
return result
result.append(now.data)
preorderTraversal(now.left, result)
preorderTraversal(now.right, result)
return result print(preorderTraversal(binaryTree))

执行结果:[0, 1, 3, 4, 2, 5, 6],是不是和我们之前手动遍历的结果一样呢。

中序遍历

中序遍历的顺序是:先遍历树的左节点,再遍历树的父节点,再遍历树的右节点。

对于我们上面创建的二叉树,它的中序遍历结果就是:3 -> 1 -> 4 -> 0 -> 5 -> 2 -> 6

在前序遍历的时候是先遍历父节点,所以result.append(now.data),就在遍历左节点和右节点的前面。

而中序遍历要先遍历左节点,所以result.append(now.data)就要在遍历左节点的后面,遍历右节点的前面。

def intermediateTraversal(now, result=[]):
if now == None:
return result
intermediateTraversal(now.left, result)
result.append(now.data)
intermediateTraversal(now.right, result)
return result print(intermediateTraversal(binaryTree))

执行结果:[3, 1, 4, 0, 5, 2, 6]

后序遍历

后序遍历顺序是:先遍历树的左节点,再遍历树的右节点,再遍历树的父节点。

对于我们上面创建的二叉树,它的后序遍历结果是:3 -> 4 -> 1 -> 5 -> 6 -> 2 -> 0

相应的递归方程为:

def postorderTraversal(now, result=[]):
if now == None:
return
postorderTraversal(now.left, result)
postorderTraversal(now.right, result)
result.append(now.data)
return result print(postorderTraversal(binaryTree))

执行结果:[3, 4, 1, 5, 6, 2, 0]

好,今天我们关于二叉树的三序遍历就介绍到这里了,接下来我们会接着介绍更多的二叉树类型以及应用,记得关注我的文章。关于三序遍历,你还有其他的实现方法吗,留言告诉我们把。

数据结构-二叉树(1)以及前序、中序、后序遍历(python实现)的更多相关文章

  1. LeetCode:二叉树的前、中、后序遍历

    描述: ------------------------------------------------------- 前序遍历: Given a binary tree, return the pr ...

  2. SDUT OJ 数据结构实验之二叉树八:(中序后序)求二叉树的深度

    数据结构实验之二叉树八:(中序后序)求二叉树的深度 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Probl ...

  3. SDUT-2804_数据结构实验之二叉树八:(中序后序)求二叉树的深度

    数据结构实验之二叉树八:(中序后序)求二叉树的深度 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 已知一颗二叉树的中序 ...

  4. 算法进阶面试题03——构造数组的MaxTree、最大子矩阵的大小、2017京东环形烽火台问题、介绍Morris遍历并实现前序/中序/后序

    接着第二课的内容和带点第三课的内容. (回顾)准备一个栈,从大到小排列,具体参考上一课.... 构造数组的MaxTree [题目] 定义二叉树如下: public class Node{ public ...

  5. 二叉树 遍历 先序 中序 后序 深度 广度 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  6. 前序+中序->后序 中序+后序->前序

    前序+中序->后序 #include <bits/stdc++.h> using namespace std; struct node { char elem; node* l; n ...

  7. 【C&数据结构】---关于链表结构的前序插入和后序插入

    刷LeetCode题目,需要用到链表的知识,忽然发现自己对于链表的插入已经忘得差不多了,以前总觉得理解了记住了,但是发现真的好记性不如烂笔头,每一次得学习没有总结输出,基本等于没有学习.连复盘得机会都 ...

  8. 五二不休息,今天也学习,从JS执行栈角度图解递归以及二叉树的前、中、后遍历的底层差异

    壹 ❀ 引 想必凡是接触过二叉树算法的同学,在刚上手那会,一定都经历过题目无从下手,甚至连题解都看不懂的痛苦.由于leetcode不方便调试,题目做错了也不知道错在哪里,最后无奈的cv答案后心里还不断 ...

  9. 给出 中序&后序 序列 建树;给出 先序&中序 序列 建树

    已知 中序&后序  建立二叉树: SDUT 1489 Description  已知一棵二叉树的中序遍历和后序遍历,求二叉树的先序遍历 Input  输入数据有多组,第一行是一个整数t (t& ...

  10. 【11】-java递归和非递归二叉树前序中序后序遍历

    二叉树的遍历 对于二叉树来讲最主要.最基本的运算是遍历. 遍历二叉树 是指以一定的次序访问二叉树中的每个结点.所谓 访问结点 是指对结点进行各种操作的简称.例如,查询结点数据域的内容,或输出它的值,或 ...

随机推荐

  1. WP8.1使用HttpClient类

    Uri uri = new Uri("http://www.cnsos.net/weburl/index.htm", UriKind.Absolute); HttpClient m ...

  2. JavaScript API for Office Outlook Add-in - “一页纸文档“

    上一篇文章 Office Add-in Model 为 Outlook Mail Add-in 提供的 JavaScript API 介绍 ,简单地在表格中列出了所有的 Object 定义,但是个人感 ...

  3. 为什么使用剪切板时都用GlobalAlloc分配内存(历史遗留问题,其实没关系了)

    我在使用剪切板时,发现通用的都是使用GlobalAlloc来分配内存,我就想不是说在Win32中GlobalAlloc和LocalAlloc是一样的那为什么不用LocalAlloc呢,原谅我的好奇心吧 ...

  4. 初探 C# 8 的 Nullable Reference Types

    溫馨提醒:本文提及的 C# 8 新功能雖已通過提案,但不代表將來 C# 8 正式發布時一定會納入.這表示我這篇筆記有可能白寫了,也表示您不必急著瞭解這項新功能的所有細節,可能只要瞄一下底下的「概要」說 ...

  5. 10 table标签

    <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...

  6. 使用BurpSuite的Collaborator查找.Onion隐藏服务的真实IP地址

    本文转载!!! 原文地址:http://www.4hou.com/technology/10367.html 翻译来自:http://digitalforensicstips.com/2017/11/ ...

  7. 附008.Kubernetes TLS证书介绍及创建

    一 Kubernetes证书 1.1 TLS Kubernetes系统的各个组件需要使用TLS证书对其通信加密以及授权认证,建议在部署之前先生成相关的TLS证书. 1.2 CA证书创建方式 kuber ...

  8. 【IDE】idea在debug模式启动非常慢,debug模式一直在启动中状态

    现象:一直处于启动中状态,日志刷的很慢,非debug模式正常启动: 最终解决方式:下图按钮,取消所有打过的断点,问题解决

  9. laravel中的构造函数依赖注入理解

    laravel中的自动依赖注入是非常强大的,刚开始会疑惑为什么只要在构造函数中传入一个强制类型的变量(就是参数有类型限制)过去就行了? 通过查看源码即查阅资料发现其实这其中有一个php技术,就是反射技 ...

  10. 学习kafka自己发生的几个小错误记录

    一.  The method iterator() is ambiguous ConsumerIterator<byte[],byte[]> it =stream.iterator(); ...