✅作者简介:大家好,我是Philosophy7?让我们一起共同进步吧! 个人主页:Philosophy7的csdn博客
系列专栏: 数据结构与算法
哲学语录: 承认自己的无知,乃是开启智慧的大门
如果觉得博主的文章还不错的话,请点赞+收藏⭐️+留言支持一下博>主哦
树和图是典型的非线性结构,现在就让我们来了解一下树的知识吧
学习目标
- 了解树的基本概念和术语
- 掌握二叉树的相关概念
生活中的树,就含有很多的树叶,我们数据结构当中所述说的树,肯定也要与实际生活相贴切。因此数据结构中的树也有大量叶子。在这里我们就来介绍一下关于树的相关概念
二叉树是树的一种特殊形式。简单的来说就是,任意结点最多只能拥有两个子节点。
如图所示:
二叉树结点的两个子结点,一个被称为左子结点,一个被称为右子结点。
二叉树还有两种特殊的形式: 一个被称为满二叉树,一个被称为完全二叉树
定义:一颗二叉树中,只有最下面两层结点的度可以小于2,并且最下层的叶子结点靠在最左的若干位置上,这样的树就被称为完全二叉树。
特点:
通俗来讲就是除了叶子结点,每个结点都有两个子结点。
满二叉树的性质:
package com.philosophy7.binary;
public class BinaryTreeNode {
//结点数据
private String data;
//左子结点 + 右子结点
private BinaryTreeNode leftChild;
private BinaryTreeNode rightChild;
public BinaryTreeNode() {
}
public BinaryTreeNode(String data, BinaryTreeNode leftChild, BinaryTreeNode rightChild) {
this.data = data;
this.leftChild = leftChild;
this.rightChild = rightChild;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public BinaryTreeNode getLeftChild() {
return leftChild;
}
public void setLeftChild(BinaryTreeNode leftChild) {
this.leftChild = leftChild;
}
public BinaryTreeNode getRightChild() {
return rightChild;
}
public void setRightChild(BinaryTreeNode rightChild) {
this.rightChild = rightChild;
}
}
package com.philosophy7.binary;
/*
创建二叉树
初始化根节点
初始化空的二叉树
*/
public class BinaryTree {
private BinaryTreeNode root; //初始化根节点
//初始化一个二叉树
public BinaryTree(){
}
public BinaryTreeNode getRoot() {
return root;
}
public void setRoot(BinaryTreeNode root) {
this.root = root;
}
}
package com.philosophy7.binary;
public class BinaryTreeTest {
public static void main(String[] args) {
BinaryTree binaryTree = new BinaryTree(); //空的二叉树
//创建结点
BinaryTreeNode dNode = new BinaryTreeNode("D",null,null);
BinaryTreeNode eNode = new BinaryTreeNode("E",null,null);
BinaryTreeNode fNode = new BinaryTreeNode("F",null,null);
BinaryTreeNode cNode = new BinaryTreeNode("C",fNode,null);
BinaryTreeNode bNode = new BinaryTreeNode("B",dNode,eNode);
BinaryTreeNode root = new BinaryTreeNode("A",bNode,cNode);
//创建二叉树
binaryTree.setRoot(root);
}
}
二叉树的遍历可分为
这是一种抽象的算法思想,决定着访问某些复杂数据结构的顺序。比如我们常见的数据结构树和图这些复杂的数据结构,深度优先遍历和广度优先遍历经常会被提及到。
深度优先遍历,顾名思义,就是直接深入到底的一种访问方式。
下面我们通过二叉树的先序遍历、中序遍历、后序遍历,来一一介绍深度优先是怎么回事。
先序遍历:
访问顺序是: 先根节点 --> 左子树 --> 右子树
中序遍历:
访问顺序是: 先左子树 --> 根节点 --> 右子树
后序遍历:
访问顺序是: 先左子树 --> 右子树 --> 根节点
在这里我们使用递归的方式来实现二叉树的深度优先遍历
//先序遍历
public static void preOrderTraver(BinaryTreeNode node){
if (node == null){
return;
}
System.out.print(node.getData() + "--->");
preOrderTraver(node.getLeftChild());
preOrderTraver(node.getRightChild());
}
//中序遍历
public static void inOrderTraver(BinaryTreeNode node){
if (node == null){
return;
}
inOrderTraver(node.getLeftChild());
System.out.print(node.getData() + "--->");
inOrderTraver(node.getRightChild());
}
//后序遍历
public static void postOrderTraver(BinaryTreeNode node){
if (node == null){
return;
}
postOrderTraver(node.getLeftChild());
postOrderTraver(node.getRightChild());
System.out.print(node.getData() + "--->");
}
上面我们已经了解了深度优先遍历,可见深度优先遍历是直接深入进去,那么广度优先恰恰相反:
它是访问一层然后遍历一层 : 从上到下,从左到右
实现层序遍历的方式,我们需要借助另一种数据结构,那就是队列
层序遍历的过程:
①根节点A入队,然后出队,输出结点A信息,并得到结点A的左子树和右子树,让结点B和C入队。
②结点B出队 输出结点B 并得到结点B的左子树和右子树。让结点D和E入队
③结点C出队 输出结点C 并得到其左子树和右子树 让其入队
④结点D出队,输出结点D 由于该结点是叶子结点 所以没有新结点入队 了
⑤结点E出队 输出结点E 同上述一样
⑥结点F出队 输出结点F 同上述一样。
//层序遍历
public static void levelOrderTraversal(BinaryTreeNode node){
if (node == null) {
return;
}
Queue<BinaryTreeNode> queue = new LinkedList<>();
queue.offer(node);
while (!queue.isEmpty()){
BinaryTreeNode top = queue.poll();
System.out.print(top.getData() + "-->");
if (top.getLeftChild() != null){
queue.offer(top.getLeftChild());
}
if (top.getRightChild()!=null){
queue.offer(top.getRightChild());
}
}
}