补充5:二叉树的实现

二叉树结点数据结构

public class TreeNode{
public int key = 0;
public String data = null;
public boolean isVisited = false;
public TreeNode leftChild = null;
public TreeNode rightChild = null;

public TreeNode(int key,String data){
this.key = key;
this.data = data;
this.leftChild = null;
this.rightChild = null;
}
}

初始化根节点

TreeNode root = null;
public javatest(){
root = new TreeNode(1,"root A");
}

创建二叉树

public void createBinTree(TreeNode root){
TreeNode newNodeB = new TreeNode(2,"B");
TreeNode newNodeC = new TreeNode(3,"C");
TreeNode newNodeD = new TreeNode(4,"D");
TreeNode newNodeE = new TreeNode(5,"E");
TreeNode newNodeF = new TreeNode(6,"F");

root.leftChild = newNodeB;
                root.rightChild = newNodeC;
                root.leftChild.leftChild = newNodeD;
                root.leftChild.rightChild = newNodeE;
                root.rightChild.rightChild = newNodeF;

}

访问节点

    public void visted(TreeNode subTree) {
        subTree.isVisited = true;
        System.out.println("key:" + subTree.key + "--name:" + subTree.data);
    }

递归与非递归进行前中后序遍历

前序遍历

    // 前序遍历
    public void preOrder(TreeNode subTree) {
        if (subTree != null) {
            visted(subTree);
            preOrder(subTree.leftChild);
            preOrder(subTree.rightChild);
        }
    }

非递归借助栈来实现

1.定义node来遍历二叉树,定义栈来储存二叉树结点

2.利用while循环,一开始node指向根节点,访问node,并入栈,将node更新为左子树,继续循环;当node为null时循环停止,此时node代表的是最左节点的左节点,为null时表示最左节点和其左子树打印完毕。

3.接下来需要打印左节点的右子树,取出栈顶元素,并将node更新为栈顶元素的右子树。

    // 前序遍历的非递归实现
    public void nonRecPreOrder(TreeNode root) {
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode node = root;
        while (node != null || stack.size() > 0) {
            while (node != null) {
                visted(node);
                stack.push(node);
                node = node.leftChild;
            }
            while (stack.size() > 0) {
                node = stack.pop();
                node = node.rightChild;
            }
        }
    }

中序遍历

    // 中序遍历
    public void inOrder(TreeNode subTree) {
        if (subTree != null) {
            inOrder(subTree.leftChild);
            visted(subTree);
            inOrder(subTree.rightChild);
        }
    }

非递归过程

1.定义node来遍历二叉树,定义栈来储存二叉树结点

2.利用while循环,一开始node指向根节点,入栈,然后将node更新为左子树,继续循环;直到node为null时第二层while循环停止,此时node代表最左节点的左节点。

3.接下来需要打印最左节点的左子树;因为左字树为空,所以直接打印他的根,取出栈顶元素,这就是最后一颗树的根,打印,删除栈顶结点,将node更新为栈顶元素的右结点;

    // 中序遍历的非递归实现
    public void nonRecInOrder(TreeNode root) {
        Stack<TreeNode> stack = new Stack<javatest.TreeNode>();
        TreeNode node = root;
        while (node != null || stack.size() > 0) {
            // 存在左子树
            while (node != null) {
                stack.push(node);
                node = node.leftChild;
            }
            // 栈非空
            if (stack.size() > 0) {
                node = stack.pop();
                visted(node);
                node = node.rightChild;
            }
        }
    }

后序遍历

    // 后续遍历
    public void postOrder(TreeNode subTree) {
        if (subTree != null) {
            postOrder(subTree.leftChild);
            postOrder(subTree.rightChild);
            visted(subTree);
        }
    }

非递归过程

1.循环将左子树左节点全部入栈

2.入栈结束,当前root为最左节点的左节点;当前节点无右子树或右子树已经输出,则访问当前节点后用node记录刚访问过的节点,root = stack.pop();更新root为栈内下一元素。

3.当前root有右子树时,右子树入栈,当前节点更新为节点的右子树。

    // 后序遍历的非递归实现
    public void noRecPostOrder(TreeNode root) {
        Stack<TreeNode> stack = new Stack<javatest.TreeNode>();
        TreeNode node = root;
        while (root!= null) {
            // 左子树入栈
            for (; root.leftChild != null; root = root.leftChild) {
                stack.push(root);
            }
            // 当前结点无右子树或右子树已经输出
            while (root != null && (root.rightChild == null || root.rightChild == node)) {
                visted(root);
                // 纪录上一个已输出结点
                node = root;
                if (stack.empty())
                    return;
                root = stack.pop();
            }
            // 处理右子树
            stack.push(root);
            root = root.rightChild;
        }
    }

完整测试

import java.util.Stack;
public class javatest {

TreeNode root = null;

public class TreeNode{
public int key = 0;
public String data = null;
public boolean isVisited = false;
public TreeNode leftChild = null;
public TreeNode rightChild = null;

public TreeNode(int key,String data){
this.key = key;
this.data = data;
this.leftChild = null;
this.rightChild = null;
}
}

public javatest(){
root = new TreeNode(1,"root A");
}

public void createBinTree(TreeNode root){
TreeNode newNodeB = new TreeNode(2,"B");
TreeNode newNodeC = new TreeNode(3,"C");
TreeNode newNodeD = new TreeNode(4,"D");
TreeNode newNodeE = new TreeNode(5,"E");
TreeNode newNodeF = new TreeNode(6,"F");

root.leftChild = newNodeB;
                root.rightChild = newNodeC;
                root.leftChild.leftChild = newNodeD;
                root.leftChild.rightChild = newNodeE;
                root.rightChild.rightChild = newNodeF;

}




    // 前序遍历
    public void preOrder(TreeNode subTree) {
        if (subTree != null) {
            visted(subTree);
            preOrder(subTree.leftChild);
            preOrder(subTree.rightChild);
        }
    }


    // 中序遍历
    public void inOrder(TreeNode subTree) {
        if (subTree != null) {
            inOrder(subTree.leftChild);
            visted(subTree);
            inOrder(subTree.rightChild);
        }
    }


    // 后续遍历
    public void postOrder(TreeNode subTree) {
        if (subTree != null) {
            postOrder(subTree.leftChild);
            postOrder(subTree.rightChild);
            visted(subTree);
        }
    }
    // 前序遍历的非递归实现
    public void nonRecPreOrder(TreeNode p) {
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode node = p;
        while (node != null || stack.size() > 0) {
            while (node != null) {
                visted(node);
                stack.push(node);
                node = node.leftChild;
            }
            while (stack.size() > 0) {
                node = stack.pop();
                node = node.rightChild;
            }
        }
    }


    // 中序遍历的非递归实现
    public void nonRecInOrder(TreeNode p) {
        Stack<TreeNode> stack = new Stack<javatest.TreeNode>();
        TreeNode node = p;
        while (node != null || stack.size() > 0) {
            // 存在左子树
            while (node != null) {
                stack.push(node);
                node = node.leftChild;
            }
            // 栈非空
            if (stack.size() > 0) {
                node = stack.pop();
                visted(node);
                node = node.rightChild;
            }
        }
    }


    // 后序遍历的非递归实现
    public void noRecPostOrder(TreeNode root) {
        Stack<TreeNode> stack = new Stack<javatest.TreeNode>();
        TreeNode node = root;
        while (root!= null) {
            // 左子树入栈
            for (; root.leftChild != null; root = root.leftChild) {
                stack.push(root);
            }
            // 当前结点无右子树或右子树已经输出
            while (root != null && (root.rightChild == null || root.rightChild == node)) {
                visted(root);
                // 纪录上一个已输出结点
                node = root;
                if (stack.empty())
                    return;
                root = stack.pop();
            }
            // 处理右子树
            stack.push(root);
            root = root.rightChild;
        }
    }


    public void visted(TreeNode subTree) {
        subTree.isVisited = true;
        System.out.println("key:" + subTree.key + "--name:" + subTree.data);
    }


    // 测试
    public static void main(String[] args) {
        javatest bt = new javatest();
        bt.createBinTree(bt.root);


        System.out.println("*******(前序遍历)[ABDECF]遍历*****************");
        bt.preOrder(bt.root);


        System.out.println("*******(中序遍历)[DBEACF]遍历*****************");
        bt.inOrder(bt.root);


        System.out.println("*******(后序遍历)[DEBFCA]遍历*****************");
        bt.postOrder(bt.root);


        System.out.println("***非递归实现****(前序遍历)[ABDECF]遍历*****************");
        bt.nonRecPreOrder(bt.root);


        System.out.println("***非递归实现****(中序遍历)[DBEACF]遍历*****************");
        bt.nonRecInOrder(bt.root);


        System.out.println("***非递归实现****(后序遍历)[DEBFCA]遍历*****************");
        bt.noRecPostOrder(bt.root);


    }

}


结果:

*******(前序遍历)[ABDECF]遍历*****************
key:1--name:root A
key:2--name:B
key:4--name:D
key:5--name:E
key:3--name:C
key:6--name:F
*******(中序遍历)[DBEACF]遍历*****************
key:4--name:D
key:2--name:B
key:5--name:E
key:1--name:root A
key:3--name:C
key:6--name:F
*******(后序遍历)[DEBFCA]遍历*****************
key:4--name:D
key:5--name:E
key:2--name:B
key:6--name:F
key:3--name:C
key:1--name:root A
***非递归实现****(前序遍历)[ABDECF]遍历*****************
key:1--name:root A
key:2--name:B
key:4--name:D
key:3--name:C
key:6--name:F
***非递归实现****(中序遍历)[DBEACF]遍历*****************
key:4--name:D
key:2--name:B
key:5--name:E
key:1--name:root A
key:3--name:C
key:6--name:F
***非递归实现****(后序遍历)[DEBFCA]遍历*****************
key:4--name:D
key:5--name:E
key:2--name:B
key:6--name:F
key:3--name:C
key:1--name:root A




猜你喜欢

转载自blog.csdn.net/cherishgf/article/details/80824845