Java:二叉树Binary Tree
目录
3.1前序遍历(DLR, Data,LeftChild,Rchild)
1.创建TreeNode
首先先创建单个节点,就叫TreeNode吧:
/二叉树节点类
public class TreeNode {
private TreeNode left;
private TreeNode right;
private int data;
public TreeNode(){}
public TreeNode(int data) {
this.data = data;
}
public void setLeft(TreeNode left) {
this.left = left;
}
public void setRight(TreeNode right) {
this.right = right;
}
public void setData() {
this.data = data;
}
public TreeNode getLeft() {
return this.left;
}
public TreeNode getRight() {
return this.right;
}
public int getData() {
return data;
}
}
2.创建Binary Tree类:
- 创建根节点root
//根节点 root node
public TreeNode root;
- 创建insert方法,构造二叉树
//insert node
public void insert(TreeNode node) {
if (root == null) {
root = node;
return;
}
//保存当前节点
TreeNode current = root;
while (true) {
if (node.getData() < current.getData()) {
if (current.getLeft() == null) {
current.setLeft(node);
return;
}
else {
current = current.getLeft();
}
}
else {
if (current.getRight() == null) {
current.setRight(node);
return;
}
else {
current = current.getRight();
}
}
}
}
data比当前current节点的data小的在其左子树,大的在右子树。通过不断更新current,最终节点会被在正确的位置插入。
3.遍历方法
3.1前序遍历(DLR, Data,LeftChild,Rchild)
- 前序遍历的递归方法
// preorder traversal 1.recursive method
public void preorder_traversal_1(TreeNode root) {
if(root != null) {
System.out.print(root.getData() + " ");
if(root.getLeft() != null) {
preorder_traversal_1(root.getLeft());
}
if(root.getRight() != null) {
preorder_traversal_1(root.getRight());
}
}
}
- 前序遍历的非递归方法
// preorder traversal 2.non-recursive method
public void preorder_traversal_2(TreeNode root) {
if (root != null) {
Stack<TreeNode> stack = new Stack<TreeNode>();
while (!stack.empty() || root != null) {
while (root != null) {
System.out.print(root.getData() + " ");
stack.push(root);
root = root.getLeft();
}
root = stack.pop();
root = root.getRight();
}
}
}
3.2中序遍历(LDR)
- 中序遍历的递归方法
// inorder traversal 1.recursive method
public void inorder_traversal_1(TreeNode root) {
if(root != null) {
if(root.getLeft() != null) {
inorder_traversal_1(root.getLeft());
}
System.out.print(root.getData() + " ");
if(root.getRight() != null) {
inorder_traversal_1(root.getRight());
}
}
}
- 中序遍历的非递归方法
//inorder traversal 2.non-recursive method
public void inorder_traversal_2(TreeNode root) {
if (root != null) {
Stack<TreeNode> stack = new Stack<TreeNode>();
while (!stack.empty() || root != null) {
while (root != null) {
stack.push(root);
root = root.getLeft();
}
root = stack.pop();
System.out.print(root.getData() + " ");
root = root.getRight();
}
}
}
3.3后序遍历(LRD)
- 后序遍历的递归方法
// postorder traversal 1.recursive method
public void postorder_traversal_1(TreeNode root) {
if(root != null) {
if(root.getLeft() != null) {
postorder_traversal_1(root.getLeft());
}
if(root.getRight() != null) {
postorder_traversal_1(root.getRight());
}
System.out.print(root.getData() + " ");
}
}
- 后序遍历的非递归方法1
// postorder traversal 2.non-recursive method
public void postorder_traversal_2(TreeNode root) {
if (root != null) {
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode pre = root;
while (!stack.empty() || root != null) {
while (root != null) {
stack.push(root);
root = root.getLeft();
}
root = stack.peek().getRight();
if (root == null || root == pre) {
//若栈顶节点的右节点为空或者已经visit过,则按顺序应该访问栈顶节点
root = stack.pop();
System.out.print(root.getData() + " ");
//prev用来标记已经visit过这个节点
pre = root;
root = null;
}
}
}
}
- 后序遍历的非递归方法2--双栈法
-
// postorder traversal 3.double stack method public void postorder_traversal_3(TreeNode root) { if (root != null) { Stack<TreeNode> stack = new Stack<TreeNode>(); Stack<TreeNode> result = new Stack<TreeNode>(); while (!stack.empty() || root != null) { while (root != null) { stack.push(root); result.push(root); root = root.getRight(); } if (!stack.empty()) root = stack.pop().getLeft(); } while (!result.empty()) { root = result.pop(); System.out.print(root.getData() + " "); } } }
4.测试
对三种遍历方法的递归方法进行测试:
public static void main(String[] args) {
int[] test = new int[] {9,6,5,7,3,8,2,1,4,0};
BinaryTree tree = new BinaryTree();
for(int i = 0; i < test.length; i++) {
TreeNode node = new TreeNode(test[i]);
tree.insert(node);
}
System.out.println("Inorder Traversal:");
tree.inorder_traversal_1(tree.root);
System.out.println();
System.out.println("preorder Traversal:");
tree.preorder_traversal_1(tree.root);
System.out.println();
System.out.println("postorder Traversal:");
tree.postorder_traversal_1(tree.root);
}
测试结果:
Inorder Traversal:
0 1 2 3 4 5 6 7 8 9
preorder Traversal:
9 6 5 3 2 1 0 4 7 8
postorder Traversal:
0 1 2 4 3 5 8 7 6 9
由结果可见,中序遍历的结果是自动将测试数据按照从小到大的顺序排列好的。
对三种非递归的遍历方法进行测试,输出结果同样正确,nice!