import java.util.*;
public class TreeNode {
private int value; //节点的值
private TreeNode node; //此节点,数据类型为Node
private TreeNode left; //此节点的左子节点,数据类型为Node
private TreeNode right; //此节点的右子节点,数据类型为Node
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public TreeNode getNode() {
return node;
}
public void setNode(TreeNode node) {
this.node = node;
}
public TreeNode getLeft() {
return left;
}
public void setLeft(TreeNode left) {
this.left = left;
}
public TreeNode getRight() {
return right;
}
public void setRight(TreeNode right) {
this.right = right;
}
public TreeNode(int value) {
this.value=value;
this.left=null;
this.right=null;
}
public String toString() { //自定义的toString方法,为了方便之后的输出
return this.value+"";
}
public static void create(int[] datas, List<TreeNode> list) {
//将数组里面的东西变成节点的形式
for(int i=0;i<datas.length;i++) {
TreeNode node=new TreeNode(datas[i]);
list.add(node);
}
//节点关联成树
for(int index=0;index<list.size()/2-1;index++) {
list.get(index).setLeft(list.get(index*2+1));
//编号为n的节点他的左子节点编号为2*n 右子节点编号为2*n+1 但是因为list从0开始编号,所以还要+1
list.get(index).setRight(list.get(index*2+2)); //与上同理
}
//单独处理最后一个父节点 ,list.size()/2-1进行设置,避免单孩子情况
int index=list.size()/2-1;
list.get(index).setLeft(list.get(index*2+1));
if(list.size()%2==1) {
//如果有奇数个节点,最后一个父节点才有右子节点
list.get(index).setRight(list.get(index * 2 + 2));
}
}
public static void preTraversal(TreeNode node){
if (node == null) //很重要,必须加上 当遇到叶子节点用来停止向下遍历
{
return;
}
System.out.print(node.getValue()+" ");//放在第一个为前序,第二中序,第三后序
preTraversal(node.getLeft());
preTraversal(node.getRight());
}
public static void main(String[] args) {
int []arr={1,2,3,4,5,6,7,8};
List<TreeNode> list=new ArrayList<>();
create(arr,list);
TreeNode treeNode = list.get(0);
preTraversal(treeNode);
}
}
非递归方式实现二叉树:
非递归前序
public static void preOrderTraversalbyLoop(DiGuiTreeNode node){
Stack<DiGuiTreeNode> stack = new Stack();
DiGuiTreeNode p = node;
while(p!=null || !stack.isEmpty()){
while(p!=null){
//当p不为空时,就读取p的值,并不断更新p为其左子节点,即不断读取左子节点
System.out.print(p.getValue()+" ");
stack.push(p); //将p入栈
p = p.getLeft();
}
if(!stack.isEmpty()){
p = stack.pop();
p = p.getRight();
}
}
}
非递归中序:
public static void preOrderTraversalbyLoop(DiGuiTreeNode node){
Stack<DiGuiTreeNode> stack = new Stack();
DiGuiTreeNode p = node;
while(p!=null || !stack.isEmpty()){
while(p!=null){
//当p不为空时,就读取p的值,并不断更新p为其左子节点,即不断读取左子节点
stack.push(p); //将p入栈
p = p.getLeft();
}
if(!stack.isEmpty()){
p = stack.pop();
System.out.print(p.getValue()+" ");
p = p.getRight();
}
}
}
非递归后序
二叉树的后序非递归遍历就比较难写,因为涉及到判断节点的访问状态…
现在有个很巧妙的方法:
前序:根->左->右
后序:左->右->根
那么可以把后序当作:根->右->左,然后再反转一下即可。
public static ArrayList<Integer> preOrderTraversalbyLoop(DiGuiTreeNode node){
ArrayList<Integer> list = new ArrayList<>();
Stack<DiGuiTreeNode> stack = new Stack();
DiGuiTreeNode p = node;
while(p!=null || !stack.isEmpty()){
while(p!=null){
list.add(p.getValue());
//当p不为空时,就读取p的值,并不断更新p为其右子节点,即不断读取左子节点
stack.push(p); //将p入栈
p = p.getRight();
}
if(!stack.isEmpty()){
p = stack.pop();
p = p.getLeft();
}
}
Collections.reverse(list);
return list;
}
参考:https://blog.csdn.net/weixin_42636552/article/details/82973190