二叉树遍历

二分搜索树(Binary Search Tree)

这一生的挚爱 提交于 2020-04-04 09:12:11
目录 什么是二叉树? 什么是二分搜索树? 二分搜索树的基本操作 二分搜索树添加新元素 二分搜索树的遍历(包含非递归实现) 删除二分搜索树中的元素 什么是二叉树?   在实现二分搜索树之前,我们先思考一下,为什么要有树这种数据结构呢?我们通过企业的组织机构、文件存储、数据库索引等这些常见的应用会发现,将数据使用树结构存储后,会出奇的高效,树结构本身是一种天然的组织结构。常见的树结构有:二分搜索树、平衡二叉树(常见的平衡二叉树有AVL和红黑树)、堆、并查集、线段树、Trie等。Trie又叫字典树或前缀树。   树和链表一样,都属于动态数据结构,由于二分搜索树是二叉树的一种,我们先来说说什么是二叉树。二叉树具有 唯一的根节点 ,二叉树每个节点 最多 有两个孩子节点,二叉树的每个节点 最多有一个父亲节点 ,二叉树具有天然递归结构,每个节点的左子数也是一棵二叉树,每个节点的右子树也是一颗二叉树。二叉树如下图: 什么是二分搜索树?   二分搜索树也是一种二叉树,但二分搜索树种每个节点的值都要大于其左子树所有节点的值,小于其右子树所有节点的值,每一棵子树也是二分搜索树。正因为二分搜索树的这种性质,二分搜索树存储的元素必须具有可比较性。下图就是一棵二分搜索树: 我们可以根据二分搜索树的特点,构建一颗二分搜索树,代码实现如下: /** * 由于二分搜索树中的元素必须具有可比较性

【封装】二叉树相关算法的实验验证

天大地大妈咪最大 提交于 2020-04-01 08:34:40
二叉树的一些基本知识: 二叉树与树有许多相似之处,但二叉树不是树的特殊情形。 定义 在计算机科学中,二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。 二 叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2^{i-1}个结点; 深度为k 的二叉树至多有2^k-1个结点; 对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1。 一棵深度为k,且有2^k-1个节点称之为满二叉树;深度为k,有n个节点的二叉树,当且仅当其每一个节点都与深度为k的满二叉树中,序号为1至n的节点对应时,称之为完全二叉树。 相关术语 树的结点:包含一个数据元素及若干指向子树的分支; 孩子结点:结点的子树的根称为该结点的孩子; 双亲结点:B 结点是A 结点的孩子,则A结点是B 结点的双亲; 兄弟结点:同一双亲的孩子结点; 堂兄结点:同一层上结点; 祖先结点: 从根到该结点的所经分支上的所有结点子孙结点:以某结点为根的子树中任一结点都称为该结点的子孙 结点层:根结点的层定义为1;根的孩子为第二层结点,依此类推; 树的深度:树中最大的结点层 结点的度:结点子树的个数 树的度: 树中最大的结点度。

刷题226. Invert Binary Tree

不羁岁月 提交于 2020-03-31 08:45:12
一、题目说明 题目226. Invert Binary Tree,翻转一个二叉树。难度是Easy! 二、我的解答 这个题目,和二叉树的遍历类似。用递归方法(前、中、后序遍历,按层遍历都可以): class Solution{ public: TreeNode* invertTree(TreeNode* root){ if(root ==NULL) return root; TreeNode * p = root->left; root->left = root->right; root->right = p; root->left = invertTree(root->left); root->right = invertTree(root->right); return root; } }; 性能如下: Runtime: 4 ms, faster than 65.13% of C++ online submissions for Invert Binary Tree. Memory Usage: 10 MB, less than 5.45% of C++ online submissions for Invert Binary Tree. 三、优化措施 非递归的算法,下面用广度优先遍历实现: class Solution{ public: //non-recursive

二叉树的遍历(递归与非递归)

心不动则不痛 提交于 2020-03-24 11:59:55
非递归遍历二叉树是使用栈压栈和弹栈时机不同的思想,在非递归先序遍历中,根据"根左右"的访问顺序不同,先访问当前数据,然后依次压入右儿子和左子;在非递归后序遍历中,需要达到"左右根"的顺序,所以使用两个栈,栈2只存储访问的节点,根据先序遍历的思想修改顺序"根右左",先访问当前节点,然后依次压入左儿子和右儿子,最后输出栈2;在非递归中序遍历中,若当前节点不为空,就压栈,当前节点指向左儿子,若为空且栈不为空,就弹栈,当前节点指向右儿子. import java.util.Stack; public class TreeTraversal { public static class Node{ public int value; public Node left; public Node right; public Node(int Value) { value = Value; } } public void preOrder(Node head) { if(head != null) { System.out.print(head.value + " "); if(head.left != null) { preOrder(head.left); } if(head.right != null) { preOrder(head.right); } } } public void

二叉搜索树与双向链表

て烟熏妆下的殇ゞ 提交于 2020-03-23 17:21:25
1:题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。 为了让您更好地理解问题,以下面的二叉搜索树为例: 我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。 下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。 特别地,我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 2:题目分析 解题思路:对于二叉排序树而言,其中序遍历输出就是升序排序。那我们怎么将其做成双向链表尼?着手点肯定是中序遍历;在遍历的迭代逻辑中,我们要将前次迭代和本次迭代处理的节点,按照双向链表的要求进行处理。怎么处理尼?通过一个全局变量保存上次遍历的节点,然后再本次遍历的节点处理中进行如下操作: preNode.right =

二叉树的创建与遍历

怎甘沉沦 提交于 2020-03-21 00:18:04
此时有这样一棵树,其先序遍历:ABCDEFGH;中序遍历:CBEDFAGH;后序遍历:CEFDBHGA;想要以输入结点的方式来创建树。可以考虑一个节点创建成功在创建其左右结点,若其左右结点为空,则返回至上一个结点继续创建,直到创建完毕。 创建树的结点: class BNode{ private BNode leftChild; private BNode rightChild; private char data; public BNode() { } public BNode(char data){ this.data = data; } public BNode(BNode leftChild,BNode rightChild,char data){ this.leftChild = leftChild; this.rightChild = rightChild; this.data = data; } public BNode getLeftChild() { return leftChild; } public void setLeftChild(BNode leftChild) { this.leftChild = leftChild; } public BNode getRightChild() { return rightChild; } public void

【算法日常】二叉树常用遍历方法

坚强是说给别人听的谎言 提交于 2020-03-17 14:56:13
二叉树的遍历 本篇算一个资料整理,就是二叉树遍历方法, 有先序遍历(PreOrder)、中序遍历(InOrder)、后序遍历(PostOrder)、广度优先遍历二叉树(breadth_first_search)、深度优先遍历(depth_first_search) 示例遍历二叉树: 二叉树节点格式: class TreeNode: def __init__(self, val): self.val = val self.left = self.right = None 1. 先序遍历 PreOrder 先遍历根节点,再遍历左子树,最后遍历右子树 def pre_order(root: TreeNode) -> list: if not root: return [] return [root.val] + pre_order(root.left) + pre_order(root.right) #### 遍历结果 ## [4, 2, 1, 3, 6, 5, 7] 2. 中序遍历 InOrder 先遍历左子树,再遍历根节点,最后遍历右子树, def in_order(root: TreeNode) -> list: if not root: return [] return in_order(root.left) + [root.val] + in_order(root.right)

Java中二叉树的层序遍历

自古美人都是妖i 提交于 2020-03-17 11:08:49
二叉树除了前序遍历、中序遍历、后序遍历之外,还有一种遍历方式,那就是层序遍历,它是将二叉树按照层次进行遍历的一种方法。 首先,需要定义节点类,代码如下: public class TreeNode { int value ; TreeNode left ; TreeNode right ; public TreeNode ( ) { value = 0 ; left = right = null ; } public TreeNode ( int value ) { this . value = value ; left = right = null ; } } 层序遍历 对于代码的实现,我们可以利用队列来实现。 public void leverOrder ( TreeNode root ) { Queue < TreeNode > queue = new LinkedList < > ( ) ; if ( root != null ) { queue . offer ( root ) ; } while ( ! queue . isEmpty ( ) ) { //获取队头元素 TreeNode topNode = queue . poll ( ) ; System . out . print ( topNode . value + " " ) ; //入队孩子节点 if (

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。

无人久伴 提交于 2020-03-16 20:20:55
题目描述:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。 有关树的问题,一般可以考虑使用递归。 方法: 1.先找到根节点 2.通过中序遍历找到左子树和右子树 3.通过递归将左子树和右子树使用同样的方法分解 4.递归出口:前序遍历和中序遍历为空,则返回 注意: 1. Arrays.copyOfRange(arr,begin,end)该函数把字符串的一部分作为一个新字符串并返回,比利用循环复制数组效率要高得多。 2.数组为空和数组长度为0的区别: int[] array = null; 数组为空,此时array不指向任何对象; int[] array = new array[0]; 定义一个长度为0的数组; int[] array = new array[2]; 定义一个长度为2的数组,此时如果数组没有被初始化,默认的值为null; 一般先判断 nums 是否为空,然后再判断长度是否为0,因为可能报空指针异常,一般使用如下方法判断。 if(array == null || array.length == 0) 代码实现: /** * Definition for binary tree *

面试题 28:对称的二叉树

邮差的信 提交于 2020-03-15 23:47:09
题目描述 请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。 例如,二叉树 [1,2,2,3,4,4,3] 是对称的。 1 / \ 2 2 / \ / \ 3 4 4 3 但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的: 1 / \ 2 2 \ \ 3 3 示例 1: 输入:root = [1,2,2,3,4,4,3] 输出:true 示例 2: 输入:root = [1,2,2,null,3,null,3] 输出:false 限制: 0 <= 节点个数 <= 1000 https://leetcode-cn.com/problems/dui-cheng-de-er-cha-shu-lcof/submissions/ 思路 在前序遍历中,是先遍历左子树再遍历右子树的。 可以定义一种与前序遍历对称的遍历,先遍历右子树,再遍历左子树。 这样会发现,只要这两种遍历的结果是一样的,那就是对称的二叉树。 有个例外,对于每个节点的值相同的二叉树,遍历后的结果都是一个树,但不一定是对称的。这时需要将 null 判断也放进来。 7 / \ 7 7 / \ / 7 7 7 如上面的二叉树,两种遍历结果都是 {7, 7, 7, 7, 7, 7},但不是对称的,这时将 null 判断加进来的不一样了。 前序遍历序列为 {7, 7,