数据结构-二叉树(复制二叉树的非递归算法)

文章目录

思路

怎么写呢?

就是二叉树遍历的非递归算法,前几篇博文有讲

后序遍历值得的注意点

数据结构-二叉树(遍历二叉树的非递归算法)中有讲

复制的非递归与遍历的非递归的区别

遍历二叉树的非递归算法用到一个栈,而复制的话用到两个栈,一个存被复制的二叉树,一个存复制到的二叉树。新的二叉树永远跟着已经存在的二叉树的节奏走,已经存在的那颗二叉树找左结点,新的二叉树也找左结点,已经存在的二叉树入栈,新的二叉树也入栈。每次到根结点的时候就进行二叉树结点值的拷贝

方法的返回

拷贝方法返回新二叉树的根结点,我们需要在方法最开始把新二叉树的根结点赋值给一个新 Node,因为循环中用的是这个新 Node(存在 Node = Node->left 这样的操作),这样就不会影响最初的那个形参的值,我们最后也就可以大方的return n

Java 实现

// 结点
class Node {
    int data;
    Node left = null;
    Node right = null;
}

// 二叉树
public class BinaryTree {
    // 根结点
    private Node root;
    // 输入的数组
    private int[] arr_in;
    // 输出的数组
    private int[] arr_out;
    // 记录数组下标
    private static int index;
    
    // 初始化
    public BinaryTree(int[] arr) {
        root = new Node();
        this.arr_in = arr;
        arr_out = new int[arr.length];
        index = 0;
    }
    
    // 先序复制二叉树(非递归)根→左→右
    public Node preorderCopy(Node r, Node n) {
        Stack rStack = new Stack();
        Stack nStack = new Stack();
        Node rNode = r;
        Node nNode = n;
        while (rNode || !rStack.empty()) {
            if (rNode) {
                rStack.push(rNode);
                nNode = new Node();
                nStack.push(nNode);
                // 根
                nNode.data = rNode.data;
                // 左
                rNode = rNode.left;
                nNode = nNode.left;
            }
            else {
                Node rTop = rStack.pop();
                Node nTop = nStack.pop();
                // 右
                rNode = rTop.right;
                nNode = nTop.right;
            }
        }
        return n;
    }

    // 中序复制二叉树(非递归)左→根→右
    public Node inorderCopy(Node r, Node n) {
        Stack rStack = new Stack();
        Stack nStack = new Stack();
        Node rNode = r;
        Node nNode = n;
        while (rNode || !rStack.empty()) {
            if (rNode) {
                rStack.push(rNode);
                nNode = new Node();
                nStack.push(nNode);
                // 左
                rNode = rNode.left;
                nNode = nNode.left;
            }
            else {
                Node rTop = rStack.pop();
                Node nTop = nStack.pop();
                // 根
                nTop.data = rTop.data;
                // 右
                rNode = rNode.right;
                nNode = nNode.right;
            }
        }
        return n;
    }
    
    // 后序复制二叉树(非递归)左→右→根
    public Node postorderCopy(Node r, Node n) {
        Stack rStack = new Stack();
        Stack nStack = new Stack();
        Node rNode = r;
        Node nNode = n;
        Node rTop;
        Node nTop;
        while (rNode || !rStack.empty()) {
            if (rNode) {
                rStack.push(rNode);
                rNode = new Node();
                rStack.push(rNode);
                // 左
                rNode = rNode.left;
                nNode = nNode.left;
            }
            else {
                if (rStack.peek().right != null && rStack.peek().right != rTop) {
                    // 右
                    rNode = rNode.right;
                    nNode = nNode.right;
                }
                else {
                    rTop = rStack.pop();
                    nTop = nStack.pop();
                    // 根
                    nTop.data = rTop.data;
                    rNode = rStack.peek();
                    nNode = nStack.peek();
                }
            }
        }
        return n;
    }
}
发布了197 篇原创文章 · 获赞 62 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/abcnull/article/details/104450991