数据结构青铜到王者第九话---二叉树(2)
续接上一话
目录
一、二叉树(续)
1、二叉树的基本操作
1.1前置说明
1.2二叉树的遍历
1.2.1前中后序遍历
1.2.2层序遍历
1.3二叉树的基本操作
一、二叉树(续)
1、二叉树的基本操作
1.1前置说明
在学习二叉树的基本操作前,需先要创建一棵二叉树,然后才能学习其相关的基本操作。此处手动快速创建一棵简单的二叉树,快速进入二叉树操作学习。等 二叉树结构了解的差不多时,我们反过头再来研究二叉树真正的创建方式。
public class BinaryTree{public static class BTNode{BTNode left;BTNode right;int value;BTNode(int value){this.value = value;}} private BTNode root;public void createBinaryTree(){BTNode node1 = new BTNode(1);BTNode node2 = new BTNode(2);BTNode node3 = new BTNode(3);BTNode node4 = new BTNode(4);BTNode node5 = new BTNode(5);BTNode node6 = new BTNode(6);root = node1;node1.left = node2;node2.left = node3;node1.right = node4;node4.left = node5;node5.right = node6;}}
注意:上述代码并不是创建二叉树的方式,真正创建二叉树方式后序详解重点讲解。
在看二叉树基本操作前,我们回顾下二叉树的概念,二叉树是:
(1)空树
(2)非空:根节点,根节点的左子树、根节点的右子树组成的。
从概念中可以看出,二叉树定义是递归式的,因此后序基本操作中基本都是按照该概念实现的。
1.2二叉树的遍历
1.2.1前中后序遍历
学习二叉树结构,最简单的方式就是遍历。所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。访问结点所做的操作依赖于具体的应用问题(比如:打印节点内容、节点内容加 1)。 遍历是二叉树上最重要的操作之一,是二叉树上进行其它运算之基础。
在遍历二叉树时,如果没有进行某种约定,每个人都按照自己的方式遍历,得出的结果就比较混乱,如果按 照某种规则进行约定,则每个人对于同一棵树的遍历结果肯定是相同的。如果N代表根节点,L代表根节点的 左子树,R代表根节点的右子树,则根据遍历根节点的先后次序有以下遍历方式:
(1)NLR:前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点--->根的左子树--->根的右子树。(从根节点开始,先左后右,遇到一个结点就出一个数据)
// 前序遍历public void preOrder(TreeNode root) {if(root == null) return;System.out.print(root.val+" ");preOrder(root.left);preOrder(root.right);}
(2)LNR:中序遍历(Inorder Traversal)——根的左子树--->根节点--->根的右子树。(从根节点开始,先左后右,某一个节点的左子树都走完时出该节点数据)
// 中序遍历public void inOrder(TreeNode root) {if(root == null) return;inOrder(root.left);System.out.print(root.val+" ");inOrder(root.right);}
(3)LRN:后序遍历(Postorder Traversal)——根的左子树--->根的右子树--->根节点。(从根节点开始,先左后右,某一个节点的右子树都走完时出该节点数据)
// 后序遍历public void postOrder(TreeNode root) {if(root == null) return;postOrder(root.left);postOrder(root.right);System.out.print(root.val+" ");}
下面主要分析前序递归遍历,中序与后序图解类似
前序遍历结果:1 2 3 4 5 6
中序遍历结果:3 2 1 5 4 6
后序遍历结果:3 1 5 6 4 1
总结:
先序遍历:遇到一个出一个
特点:第一个打印根节点
中序遍历:左侧孩子结点返回时打印(左侧都走完)
特点:根节点左侧为左子树,右侧为右子树
后序遍历:右侧孩子结点返回时打印(右侧都走完)
特点:最后一个打印根节点
1.2.2层序遍历
层序遍历:除了先序遍历、中序遍历、后序遍历外,还可以对二叉树进行层序遍历。设二叉树的根节点所在 层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层 上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历。
1.2.3练习
(1)自己去多找几个二叉树的图片,分别写出对应的前中后序遍历
(2)选择
答案:
1.3二叉树的基本操作
// 获取树中节点的个数public void size(TreeNode root) {if(root == null) {return ;}nodeSize++;size(root.left);size(root.right);} // 获取叶子节点的个数public void getLeafNodeCount(TreeNode root) {if(root == null) {return;}if(root.left == null && root.right == null) {leafSize++;}getLeafNodeCount(root.left);getLeafNodeCount(root.right);}// 获取第K层节点的个数public int getKLevelNodeCount(TreeNode root,int k) {if(root == null) {return 0;}if(k == 1) {return 1;}return getKLevelNodeCount(root.left,k-1) + getKLevelNodeCount(root.right,k-1);}// 获取二叉树的高度public int getHeight(TreeNode root) {if(root == null) {return 0;}int leftHeight = getHeight(root.left);int rightHeight = getHeight(root.right);return leftHeight >rightHeight? leftHeight+1 : rightHeight+1;}// 检测值为value的元素是否存在public TreeNode findVal(TreeNode root,char val) {if(root == null) {return null;}if(root.val == val) {return root;}TreeNode leftT = findVal(root.left,val);if(leftT != null) {return leftT;}TreeNode rightT = findVal(root.right,val);if(rightT != null) {return rightT;}return null;}//判断一棵树是不是完全二叉树public boolean isCompleteTree(TreeNode root) {if (root == null) {return true;}Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);boolean foundNull = false; // 标记是否已经遇到null节点while (!queue.isEmpty()) {TreeNode current = queue.poll();if (current == null) {foundNull = true; // 遇到null节点,标记为true} else {// 如果已经遇到过null节点,但当前节点不为null,则不是完全二叉树if (foundNull) {return false;}// 将左右子节点加入队列(即使为null也要加入)queue.offer(current.left);queue.offer(current.right);}}return true;}
由于内容较多,会分为多篇讲解,预知后续内容,请看后续博客!!!