树结构简介
树是一种重要的非线性数据结构,直观地看,它是数据元素(在树中称为结点)按分支关系组织起来的结构,很象自然界中的树那样。
数的基本概念
度
树的度——也即是宽度,简单地说,就是结点的分支数。以组成该树各结点中最大的度作为该树的度,树中度为零的结点称为叶结点或终端结点。树中度不为零的结点称为分枝结点或非终端结点。除根结点外的分枝结点统称为内部结点。
就是该节点 又多少个子节点
深度
树的深度——组成该树各结点的最大层次;
层次
根结点的层次为1,其他结点的层次等于它的父结点的层次数加1.
路径
对于一棵子树中的任意两个不同的结点,如果从一个结点出发,按层次自上而下沿着一个个树枝能到达另一结点,称它们之间存在着一条路径。可用路径所经过的结点序列表示路径,路径的长度等于路径上的结点个数减1.
森林
指若干棵互不相交的树的集合
双亲节点
就是节点的父节点 ,
二叉树
二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个结点最多只能有两棵子树,且有左右之分 [1] 。
满二叉树
所有叶子节点(没有子节点的节点)都在最后一层,节点总数为2的n次方-1。
完全二叉树
所有叶子节点都在最后一层,活在倒数第二次,最后一层在左边连续,最后二层在右边连续
下列不是完全二叉树
二叉树的链式存储
思路图
实现
树类
package suanfa03;
public class twoTree {
nodeTree root;
public nodeTree getRoot() {
return root;
}
public void setRoot(nodeTree root) {
this.root = root;
}
}
节点类
package suanfa03;
public class nodeTree {
nodeTree leftNode;
int data;
nodeTree right;
public nodeTree(int data) {
this.data = data;
}
public void setLeftNode(nodeTree leftNode) {
this.leftNode = leftNode;
}
public void setRight(nodeTree right) {
this.right = right;
}
}
测试类
package suanfa03;
import static org.junit.jupiter.api.Assertions.*;
class twoTreeTest {
public static void main(String[] args) {
//创建一个空树
twoTree twoTree = new twoTree();
//创建一个根节点,并把根节点赋予树
nodeTree nodeTree = new nodeTree(1);
twoTree.setRoot(nodeTree);
nodeTree.setLeftNode(new nodeTree(2));
nodeTree.setRight(new nodeTree(3));
}
}
树的遍历
中序/前序/后序遍历,就是先去那个节点,就是什么遍历
各种顺序就是root的顺序,前序就是root/左/右 ,中序 左root右,后续 左右root
前序:1 2 4 5 3 6 7
中序:4 2 5 1 6 3 7
后序:4 5 2 6 7 3 1
中序/前序/后序遍历的实现
package suanfa03;
import static org.junit.jupiter.api.Assertions.*;
class twoTreeTest {
public static void main(String[] args) {
//创建一个空树
twoTree twoTree = new twoTree();
//创建一个根节点,并把根节点赋予树
nodeTree nodeTree = new nodeTree(1);
twoTree.setRoot(nodeTree);
suanfa03.nodeTree nodeTree2_l = new nodeTree(2);
suanfa03.nodeTree nodeTree2_r = new nodeTree(3);
nodeTree.setLeftNode(nodeTree2_l);
nodeTree.setRight(nodeTree2_r);
nodeTree2_l.setLeftNode(new nodeTree(4));
nodeTree2_l.setRight(new nodeTree(5));
nodeTree2_r.setLeftNode(new nodeTree(6));
nodeTree2_r.setRight(new nodeTree(7));
// twoTree 的中序/前序/后序遍历
twoTree.flowTree();
System.out.println("=========");
twoTree.midTree();
System.out.println("=========");
twoTree.afterTree();
}
}
twoTree类的实现
package suanfa03;
public class twoTree {
nodeTree root;
public nodeTree getRoot() {
return root;
}
public void setRoot(nodeTree root) {
this.root = root;
}
// twoTree调用nodeTree 节点进行 的中序/前序/后序遍历
public void flowTree() {
root.flowTree();
}
public void midTree() {
root.midTree();
}
public void afterTree() {
root.afterTree();
}
}
twoTree调用nodeTree
package suanfa03;
public class nodeTree {
nodeTree leftNode;
int data;
nodeTree right;
public nodeTree(int data) {
this.data = data;
}
public void setLeftNode(nodeTree leftNode) {
this.leftNode = leftNode;
}
public void setRight(nodeTree right) {
this.right = right;
}
// nodetree的中序/前序/后序遍历
public void flowTree() {
System.out.println(data);
if (leftNode!=null){
leftNode.flowTree();
}
if (right!=null){
right.flowTree();
}
}
public void midTree() {
if (leftNode!=null){
leftNode.midTree();
}
System.out.println(data);
if (right!=null){
right.midTree();
}
}
public void afterTree() {
if (leftNode!=null){
leftNode.afterTree();
}
if (right!=null){
right.afterTree();
}
System.out.println(data);
}
}
1