定义:
树形结构:树形结构指的是数据元素之间存在着“一对多”的树形关系的数据结构,是一类重要的非线性数据结构
二叉树:在计算机科学中,二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
一棵深度为k,且有2^k-1个节点的二叉树,称为满二叉树。这种树的特点是每一层上的节点数都是最大节点数。而在一棵二叉树中,除最后一层外,若其余层都是满的,并且最后一层或者是满的,或者是在右边缺少连续若干节点,则此二叉树为完全二叉树。具有n个节点的完全二叉树的深度为floor(log2n)+1。深度为k的完全二叉树,至少有2k-1个叶子节点,至多有2k-1个节点。
图示:
树结构的基本概念:
结点(Node) 表示树中的数据元素,由数据项和数据元素之间的关系组成。在图中,共有7个结点 根节点 最上面的结点称之为根,一颗树只有一个根且由根发展而来,从另外一个角度来说,每个结点都可以认为是其子树的根,例如1是所有节点的根,2是4和5的根 结点的度
(Degree of Node)
节点下面拥有子树的个数,例如1的有2,3两颗子树,所以它的度为2 树的度
(Degree of Tree)
树中各结点度的最大值,该树的度为2 分支结点
(Branch Node)
度不为0的结点,也叫非终端结点或内部结点。
例如1,2,3节点
叶子结点
(Leaf Node)
度为0的结点,也叫终端结点。
例如4,5,6,7节点
孩子(Child)
结点子树的根。
例如2,3节点是1节点的孩子,4,5节点是2节点的孩子
双亲(Parent) 结点的上层结点叫该结点的双亲。
例如1节点是2,3节点的双亲,2节点是4,5节点的孩子
......
代码实现二叉树:
java类分为树 + 节点 ,实现如下:
树:BinaryTree
/** * 二叉树 * @author Mr.Cao * */ public class BinaryTree { //根节点 private TreeNode root; /** * 查看根节点 * @return */ public TreeNode getRoot() { return root; } /** * 设置根节点 * @param root */ public void setRoot(TreeNode root) { this.root = root; } /** * 前序排序 */ public void frontShow() { this.getRoot().frontShow(); } /** * 前序排序 */ public void midShow() { this.getRoot().midShow(); } /** * 前序排序 */ public void afterShow() { this.getRoot().afterShow(); } /** * 前序搜索 * @param i * @return */ public TreeNode frontSearch(int i) { return this.root.frontSearch(i); } @Override public String toString() { return "BinaryTree [root=" + root + "]"; } }
节点:TreeNode
/** * 树的节点 * @author Mr.Cao * */ public class TreeNode { //节点的权 private int value; //左儿子 private TreeNode leftNode; //右儿子 private TreeNode rightNode; public TreeNode(int value) { this.value = value; } public TreeNode getLeftNode() { return leftNode; } public void setLeftNode(TreeNode leftNode) { this.leftNode = leftNode; } public TreeNode getRightNode() { return rightNode; } public void setRightNode(TreeNode rightNode) { this.rightNode = rightNode; } /** * 前序排序 */ public void frontShow() { System.out.println(this.value); if(this.getLeftNode() != null) { this.getLeftNode().frontShow(); } if(this.getRightNode() != null) { this.getRightNode().frontShow(); } } /** * 前序排序 */ public void midShow() { if(this.getLeftNode() != null) { this.getLeftNode().midShow(); } System.out.println(this.value); if(this.getRightNode() != null) { this.getRightNode().midShow(); } } /** * 后序排序 */ public void afterShow() { if(this.getLeftNode() != null) { this.getLeftNode().afterShow(); } if(this.getRightNode() != null) { this.getRightNode().afterShow(); } System.out.println(this.value); } /** * 前序查找 * @param i * @return */ public TreeNode frontSearch(int i) { TreeNode targ = null; //对比当前的值 if(this.value == i) { return this; } else {//当前的值不是我想要的 //查找左儿子 if(this.getLeftNode() != null) { targ = this.getLeftNode().frontSearch(i); } //左儿子找到了 if(targ != null) { return targ; } //查找右儿子 if(this.getRightNode() != null) { targ = this.getRightNode().frontSearch(i); } } return targ; } @Override public String toString() { return "TreeNode [value=" + value + ", leftNode=" + leftNode + ", rightNode=" + rightNode + "]"; } }
测试代码
public static void main(String[] args) { //创建二叉树 BinaryTree binaryTree = new BinaryTree(); //创建根节点,赋值0 TreeNode root = new TreeNode(1); //设置二叉树的根节点 binaryTree.setRoot(root); //创建左节点 TreeNode rootLeftNode = new TreeNode(2); //创建左节点 TreeNode rootRightNode = new TreeNode(3); //设置根节点的左节点 root.setLeftNode(rootLeftNode); //设置根节点的右节点 root.setRightNode(rootRightNode); //为根节点的左节点添加节点 rootLeftNode.setLeftNode(new TreeNode(4)); rootLeftNode.setRightNode(new TreeNode(5)); //为根节点的右节点添加节点 rootRightNode.setLeftNode(new TreeNode(6)); rootRightNode.setRightNode(new TreeNode(7)); System.out.println("前序排序输出二叉树"); binaryTree.frontShow(); System.out.println("中序排序输出二叉树"); binaryTree.midShow(); System.out.println("后序排序输出二叉树"); binaryTree.afterShow(); System.out.println(binaryTree.frontSearch(2)); }
输出:
前序排序输出二叉树
1
2
4
5
3
6
7
中序排序输出二叉树
4
2
5
1
6
3
7
后序排序输出二叉树
4
5
2
6
7
3
1
TreeNode [value=2, leftNode=TreeNode [value=4, leftNode=null, rightNode=null], rightNode=TreeNode [value=5, leftNode=null, rightNode=null]]