1、二叉树
树有很多种,每个结点最多只能有两个子结点的成为二叉树,二叉树的结点分为左结点和右结点。
二叉树遍历:
1、前序遍历:从二叉树的根结点出发,当第一次到达结点时就输出结点数据,按照先向左在向右的方向访问。
2、中序遍历:从二叉树的根结点出发,当第二次到达结点时就输出结点数据,按照先向左在向右的方向访问。
3、后序遍历:从二叉树的根结点出发,当第三次到达结点时就输出结点数据,按照先向左在向右的方向访问。
4、层序遍历:层次遍历就是按照树的层次自上而下的遍历二叉树**
/*** 二叉树遍历:*/public class BinaryTree {/*** 根结点*/private TreeNode rootNode;/*** 结点类*/private class TreeNode {private String name;private TreeNode left;private TreeNode right;public TreeNode(String name, TreeNode left, TreeNode right) {this.name = name;this.left = left;this.right = right;}/*** 前序遍历*/public void beforeOrder() {if (this == null) {return;}// 1、输出结点System.out.printf("%s ", this.name);// 2、前序遍历左子树if (this.left != null) {this.left.beforeOrder();}// 3、前序遍历右子树if (this.right != null) {this.right.beforeOrder();}}/*** 中序遍历*/public void middleOrder() {if (this == null) {return;}// 1、中序遍历左子树if (this.left != null) {this.left.middleOrder();}// 2、输出结点System.out.printf("%s ", this.name);// 3、中序遍历右子树if (this.right != null) {this.right.middleOrder();}}/*** 后序遍历*/public void afterOrder() {if (this == null) {return;}// 1、后序遍历左子树if (this.left != null) {this.left.afterOrder();}// 2、后序遍历右子树if (this.right != null) {this.right.afterOrder();}// 3、输出结点System.out.printf("%s ", this.name);}/*** 查找结点(前序遍历)*/public boolean beforeOrderSearch(TreeNode node) {if (this == null) {return false;}// 1、比较查找值跟当前结点是否相等,如果相等则直接返回if (Objects.equals(node.name, this.name)) {return true;}// 2、当前结点没找到的话,则继续从左子树去查找boolean bool = false;if (this.left != null) {bool = this.left.beforeOrderSearch(node);}// 3、左子树没找到的话,则继续从右子树去查找if (!bool) {if (this.right != null) {bool = this.right.beforeOrderSearch(node);}}return bool;}/*** 删除结点*/public void deleteNode(TreeNode node){// 由于结点是单向的,根据父结点可以找到子结点,而子结点找不到父结点,所以需要判断子结点是不是要删除的结点if (this == null) {return;}// 1、如果左结点就是删除结点,则将左结点设为null,直接返回if (this.left != null && Objects.equals(this.left.name, node.name)) {this.left = null;return;}// 2、如果右结点就是删除结点,则将右结点设为null,直接返回if (this.right != null && Objects.equals(this.right.name, node.name)) {this.right = null;return;}// 3、找不到删除结点,则分别向左右结点递归this.left.deleteNode(node);this.right.deleteNode(node);}}public BinaryTree() {// 初始化二叉树// A// / \// B C// / \// D ETreeNode E = new TreeNode("E", null, null);TreeNode D = new TreeNode("D", null, null);TreeNode B = new TreeNode("B", D, E);TreeNode C = new TreeNode("C", null, null);this.rootNode = new TreeNode("A", B, C);}/*** 前序遍历*/public void beforeOrderPrint() {if (rootNode == null) {System.out.println("前序遍历为空");return;}rootNode.beforeOrder();}/*** 中序遍历*/public void middleOrderPrint() {if (rootNode == null) {System.out.println("中序遍历为空");return;}rootNode.middleOrder();}/*** 后序遍历*/public void afterOrderPrint() {if (rootNode == null) {System.out.println("空树遍历为空");return;}rootNode.afterOrder();}/*** 查找(前序遍历)*/public Boolean beforeOrderSearch(String name) {if (rootNode == null) {return false;}TreeNode node = new TreeNode(name, null, null);return rootNode.beforeOrderSearch(node);}/*** 删除结点*/public void deleteNode(String name){if (rootNode == null) {System.out.println("二叉树为空,无法删除");return;}// 删除根结点时,则直接将根结点设为nullif (Objects.equals(rootNode.name, name)) {rootNode = null;return;}TreeNode node = new TreeNode(name, null, null);rootNode.deleteNode(node);}public static void main(String[] args) {BinaryTree binaryTree = new BinaryTree();// A B D E CSystem.out.print("前序遍历:");binaryTree.beforeOrderPrint();System.out.println();// D B E A CSystem.out.print("中序遍历:");binaryTree.middleOrderPrint();System.out.println();// D E B C ASystem.out.print("后序遍历:");binaryTree.afterOrderPrint();System.out.println();System.out.println("查找(前序遍历):" + binaryTree.beforeOrderSearch("D"));binaryTree.deleteNode("C");System.out.print("删除结点后:");binaryTree.beforeOrderPrint();}}
二叉树存储方式:**
1、顺序存储
2、链式存储
/**
* 《顺序存储二叉树》
* 二叉树的顺序存储结构就是使用一维数组存储二叉树中的结点,并且结点的存储位置,就是数组的下标索引。
* 从数据存储来看,数组存储方式和树的存储方式可以相互转换,即数组可以转换成树,树也可以转换成数组
*
* A[0]
* / \ 0 1 2 3 4 5 6
* B[1] C[2] ----> | | | | | | |
* / \ / \ [A, B, C, D, E, F, G]
* D[3] E[4] F[5] G[6]
*
* 顺序存储二叉树的特点:
* (1)顺序二叉树通常只考虑完全二叉树
* (2)第n个元素的左子节点为 2 * n + 1
* (3)第n个元素的右子节点为 2 * n + 2
* (4)第n个元素的父节点为 (n-1) / 2
* n:表示二叉树中的第几个元素(按0开始编号如图所示)
*
*/
public class ArrayBinaryTree {
private String[] arr;
public ArrayBinaryTree(String[] arr) {
this.arr = arr;
}
/**
* 前序遍历
*/
public void beforeOrder() {
this.beforeOrder(0);
}
private void beforeOrder(int index) {
if (index >= arr.length) {
return;
}
// 1、输出结点
System.out.printf("%s ", arr[index]);
// 2、前序遍历左结点
beforeOrder(2 * index + 1);
// 3、前序遍历右结点
beforeOrder(2 * index + 2);
}
public static void main(String[] args) {
String[] arr = new String[]{"A", "B", "C", "D", "E", "F", "G"};
ArrayBinaryTree tree = new ArrayBinaryTree(arr);
// A B D E C F G
tree.beforeOrder();
}
}
2、多叉树
在二叉树中,每个节点有数据项,最多有两个子节点。如果允许每个节点可以有更多的数据项和更多的子节点,就是多叉树(multiway tree)
