1、背景
二叉树算法,相信大家都不陌生,学习,面试,工作中我们都会遇到它,其实二叉树在IT领域应用是非常广泛的,它不仅在游戏开发中,在当前比较火的人工智能上也得到了广泛的应用。下面就java实现二叉树算法进行实现。
2、遍历二叉树几种方式
遍历二叉树有三种方式,分别是:
1.先序遍历(根->左->右),
2.中序遍历(左->根->右),
3.后序遍历(左->右->根)。
马上晒一张图,先观为敬:
先给出该图三种遍历方式路径结果:
先序:0,1,3,4,2,5,
中序:3,1,4,0,2,5,
后序:3,4,1,5,2,0,
3、二叉树算法实现
下面我们采用多种方式实现二叉树算法,首先我们定义一个二叉树实体类,如下:
class TreeNode {
int value;
TreeNode left;
TreeNode right;
public TreeNode(int value) {
this.value = value;
}
}
下面我们开始使用java代码,采用递归和非递归的方式实现算法,如下:
3.1 先序遍历
3.1.1 递归方式
public void preorderTraversal(TreeNode root, int orderMode) {
if (root == null) {
return;
}
System.out.print(root.val+",");
preorderTraversal(root.left, orderMode);
preorderTraversal(root.right, orderMode);
}
3.1.2 非递归方式
采用栈和队列结构进行实现,首先先说一下栈和队列的特点:
栈:先进后出
队列:先进先出
思想是首先将根节点压入,然后出栈时访问其左右节点 , 再然后将右子节点压入,最后将左子节点压入
// 前序遍历二叉树,广度优先 栈结构实现,将 root 压入,出栈,然后依次将 右子节点 左子节点压入
public ArrayList<Integer> preorderTraversal(TreeNode root) {
if (root == null) return null;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
ArrayList<Integer> result = new ArrayList<>();
while (!stack.isEmpty()) {
TreeNode current = stack.pop();
result.add(current.val);
if (null != current.right) {
stack.push(current.right);
}
if (null != current.left) {
stack.push(current.left);
}
}
return result;
}
//借助队列结构实现
public ArrayList<Integer> preorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<Integer>();
if (root == null) return list;
Deque<TreeNode> deque = new LinkedList();
deque.add(root);
while (!deque.isEmpty()) {
TreeNode t = deque.pop();
list.add(t.val);
if (t.left != null) deque.add(t.left);
if (t.right != null) deque.add(t.right);
}
return list;
}
3.2 中序遍历
3.2.1 递归方式
public void inorderTraversal(TreeNode root, int orderMode) {
if (root == null) {
return;
}
inorderTraversal(root.left, orderMode);
System.out.print(root.val+",");
inorderTraversal(root.right, orderMode);
}
3.2.2 非递归方式
采用栈结构,先将左节点压入栈,当节点为 null,栈顶元素出栈,获取value,将出栈元素的右节点压入栈
// 中序遍历二叉树,先将左节点压入栈,当节点为 null,栈顶元素出栈,获取value,将出栈元素的右节点压入栈
public ArrayList inorderTraversal(TreeNode root) {
if (root == null) return null;
Stack<TreeNode> stack = new Stack<>();
ArrayList<Integer> result = new ArrayList<>();
while (null != root || !stack.isEmpty()) {
if (null != root) {
stack.push(root);
root = root.left;
} else {
root = stack.pop();
result.add(root.value);
root = root.right;
}
}
return result;
}
3.3 后序遍历
3.3.1 递归方式
public void postorderTraversal(TreeNode root, int orderMode) {
if (root == null) {
return;
}
postorderTraversal(root.left, orderMode);
postorderTraversal(root.right, orderMode);
System.out.print(root.val+",");
}
3.3.2 非递归方式
深度优先,两个栈实现。在current 栈中入栈为 root,随即弹出到 back 栈;current 弹出节点如有左右节点,则按照先左后右的顺序一并入栈,之后出栈到 back中,back存储的数据依次出栈即为后序遍历序列(左->右->根)。
// 后序遍历二叉树(深度优先),两个栈实现
public ArrayList<Integer> postorderTraversal(TreeNode root) {
if (root == null) return null;
Stack<TreeNode> current = new Stack<>();
Stack<TreeNode> back = new Stack<>();
// 压入当前栈
current.push(root);
while (!current.isEmpty()) {
TreeNode node = current.pop();
// 将 current 弹出的元素压入back 栈
back.push(node);
if (null != node.left) {
current.push(node.left);
}
if (null != node.right) {
current.push(node.right);
}
}
ArrayList<Integer> result = new ArrayList<>();
while (!back.isEmpty()) {
TreeNode node = back.pop();
result.add(node.value);
}
return result;
}
4、最后给个递归测试用例
下面栗子可以参考上面的二叉树图哦
public static void main(String[] args) {
TreeNode treeNode = new TreeNode(0);
TreeNode leftNode = new TreeNode(1);
TreeNode rightNode = new TreeNode(2);
TreeNode leftleftNode = new TreeNode(3);
TreeNode leftrightNode = new TreeNode(4);
TreeNode rightrightNode = new TreeNode(5);
treeNode.left = leftNode;
treeNode.right = rightNode;
treeNode.left.left = leftleftNode;
treeNode.left.right = leftrightNode;
treeNode.right.right = rightrightNode;
//先序
System.out.print("先序:");
BinaryTree.preorderTraversal(treeNode,4);
System.out.println();
//中序
System.out.print("中序:");
BinaryTree.inorderTraversal(treeNode,4);
System.out.println();
//后序
System.out.print("后序:");
BinaryTree.postorderTraversal(treeNode,4);
}
输出结果如下:
先序:0,1,3,4,2,5,
中序:3,1,4,0,2,5,
后序:3,4,1,5,2,0,