一、树的概念
相比数组、链表、栈、队列,树是一种非线性的数据结构。树有层次关系,最高层次的节点叫做根节点。根节点的存在子节点,当一个节点没有任何子节点时,该节点被称为叶子节点。
二叉树
二叉树是一种特殊的树,它的每个节点最多只有两个节点。
二、使用Java实现树🌲
普通树的实现
树由节点组成
@Data
public class TreeNode<T> {
private T data;
private List<TreeNode<T>> subNodes;
public TreeNode(T data){
this.data = data;
}
}
构造一棵树
public class MultiNodeTree<T> {
/**
* 1
* 21 22 23
* 31 32 33 34 35 36 37 38
*/
private TreeNode<Integer> build(){
//第一层
TreeNode<Integer> root = new TreeNode<>(1);
//第二层
TreeNode<Integer> node21 = new TreeNode<>(21);
TreeNode<Integer> node22 = new TreeNode<>(22);
TreeNode<Integer> node23 = new TreeNode<>(23);
List<TreeNode<Integer>> subNodes2 = new ArrayList<>();
subNodes2.add(node21);
subNodes2.add(node22);
subNodes2.add(node23);
//第三层
TreeNode<Integer> node31 = new TreeNode<>(31);
TreeNode<Integer> node32 = new TreeNode<>(32);
TreeNode<Integer> node33 = new TreeNode<>(33);
List<TreeNode<Integer>> subNodes31 = new ArrayList<>();
subNodes31.add(node31);
subNodes31.add(node32);
subNodes31.add(node33);
TreeNode<Integer> node34 = new TreeNode<>(34);
TreeNode<Integer> node35 = new TreeNode<>(35);
TreeNode<Integer> node36 = new TreeNode<>(36);
TreeNode<Integer> node37 = new TreeNode<>(37);
TreeNode<Integer> node38 = new TreeNode<>(38);
List<TreeNode<Integer>> subNodes32 = new ArrayList<>();
subNodes32.add(node34);
subNodes32.add(node35);
subNodes32.add(node36);
subNodes32.add(node37);
subNodes32.add(node38);
root.setSubNodes(subNodes2);
node21.setSubNodes(subNodes31);
node22.setSubNodes(subNodes32);
return root;
}
}
二叉树的实现
二叉树节点比较特殊,它最多只有左右两个节点
@Data
public class BinaryTreeNode<T> {
private T data;
private BinaryTreeNode<T> leftNode;
private BinaryTreeNode<T> rightNode;
public BinaryTreeNode(T data){
this.data = data;
}
}
构造二叉树
public class BinaryTree {
/**
* 1
* 2 3
* 4 5 6 7
* 8 9
* 10
*/
public BinaryTree(){
BinaryTreeNode<Integer> node1 = new BinaryTreeNode<>(1);
BinaryTreeNode<Integer> node2 = new BinaryTreeNode<>(2);
BinaryTreeNode<Integer> node3 = new BinaryTreeNode<>(3);
BinaryTreeNode<Integer> node4 = new BinaryTreeNode<>(4);
BinaryTreeNode<Integer> node5 = new BinaryTreeNode<>(5);
BinaryTreeNode<Integer> node6 = new BinaryTreeNode<>(6);
BinaryTreeNode<Integer> node7 = new BinaryTreeNode<>(7);
BinaryTreeNode<Integer> node8 = new BinaryTreeNode<>(8);
BinaryTreeNode<Integer> node9 = new BinaryTreeNode<>(9);
BinaryTreeNode<Integer> node10 = new BinaryTreeNode<>(10);
node1.setLeftNode(node2);
node1.setRightNode(node3);
node2.setLeftNode(node4);
node2.setRightNode(node5);
node3.setLeftNode(node6);
node3.setRightNode(node7);
node4.setLeftNode(node8);
node7.setRightNode(node9);
node9.setLeftNode(node10);
root = node1;
}
}
三、树的遍历
普通树的遍历
深度优先遍历
基于递归实现深度优先遍历
/**
* 递归实现深度优先遍历
*/
public void deepFirstSearchByRecursive(List<TreeNode<T>> subNodes){
for (TreeNode<T> node : subNodes){
handleNode(node);
if(node.getSubNodes() != null){
deepFirstSearchByRecursive(node.getSubNodes());
}
}
}
基于栈实现深度优先遍历
/**
* 依赖栈实现深度优先遍历
*/
public void deepFirstSearchByStack(TreeNode<T> root){
Stack<TreeNode<T>> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()){
TreeNode<T> node = stack.pop();
handleNode(node);
if(node.getSubNodes() != null){
for (TreeNode<T> subNode : node.getSubNodes()){
stack.push(subNode);
}
}
}
}
广度优先遍历
/**
* 依赖队列实现广度优先遍历
*/
public void breadthFirstSearchByQueue(TreeNode<T> root){
Queue<TreeNode<T>> queue = new ArrayDeque<>();
queue.offer(root);
while (!queue.isEmpty()){
TreeNode<T> node = queue.poll();
handleNode(node);
if(node.getSubNodes() != null){
for (TreeNode<T> subNode : node.getSubNodes()){
queue.offer(subNode);
}
}
}
}
二叉树的遍历
除了深度优先遍历和广度优先遍历外,二叉树还存在前序遍历、中序遍历、后序遍历。
深度优先遍历
基于递归实现
//递归实现深度优先
public void dfsRecursion(BinaryTreeNode root){
if(root == null){
return;
}
appendPath(root);
dfsRecursion(root.getLeftNode());
dfsRecursion(root.getRightNode());
}
基于栈实现
//深度优先遍历
public void dfs(BinaryTreeNode root){
Stack<BinaryTreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()){
BinaryTreeNode node = stack.pop();
appendPath(node);
if(node.getRightNode() != null){
stack.push(node.getRightNode());
}
if(node.getLeftNode() != null){
stack.push(node.getLeftNode());
}
}
}
广度优先遍历
基于队列实现
//广度优先遍历
public void bfs(BinaryTreeNode root){
Queue<BinaryTreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()){
BinaryTreeNode node = queue.poll();
appendPath(node);
if(node.getLeftNode() != null){
queue.offer(node.getLeftNode());
}
if(node.getRightNode() != null){
queue.offer(node.getRightNode());
}
}
}
前序遍历
public void preOrderTraversal(BinaryTreeNode node){
if(node == null){
return;
}
path.append(node.getData()).append(",");
preOrderTraversal(node.getLeftNode());
preOrderTraversal(node.getRightNode());
}
中序遍历
public void midOrderTraversal(BinaryTreeNode node){
if(node == null){
return;
}
midOrderTraversal(node.getLeftNode());
path.append(node.getData()).append(",");
midOrderTraversal(node.getRightNode());
}
后序遍历
public void postOrderTraversal(BinaryTreeNode node){
if(node == null){
return;
}
postOrderTraversal(node.getLeftNode());
postOrderTraversal(node.getRightNode());
path.append(node.getData()).append(",");
}