📜  用于中序遍历的二叉树迭代器

📅  最后修改于: 2022-05-13 01:56:09.893000             🧑  作者: Mango

用于中序遍历的二叉树迭代器

给定一个二叉树和一个输入数组。任务是创建一个迭代器,它利用next()hasNext()函数在二叉树上执行中序遍历。

例子:

朴素的方法:一旦我们到达二叉树的叶节点,就需要一种方法来遍历祖先。 Stack 数据结构可用于此目的。

算法:

类被实例化

hasNext()函数

下一个()函数

以下是上述方法的实现

Java
// Java Program for above approach
import java.util.*;
 
// Structure of a Node
class Node {
    int data;
    Node left;
    Node right;
 
    Node(int data)
    {
        this.data = data;
        left = right = null;
    }
}
 
// Inorder Iterator class
class InorderIterator {
    private Stack traversal;
 
    InorderIterator(Node root)
    {
        traversal = new Stack();
        moveLeft(root);
    }
 
    private void moveLeft(Node current)
    {
        while (current != null) {
            traversal.push(current);
            current = current.left;
        }
    }
 
    public boolean hasNext()
    {
        return !traversal.isEmpty();
    }
 
    public Node next()
    {
        if (!hasNext())
            throw new NoSuchElementException();
 
        Node current = traversal.pop();
 
        if (current.right != null)
            moveLeft(current.right);
 
        return current;
    }
}
 
// Class to Test given set of inputs
class Test {
 
    // Driver Code
    public static void main(String args[])
    {
        Node root = new Node(8);
        root.right = new Node(9);
        root.left = new Node(3);
        root.left.left = new Node(2);
        root.left.right = new Node(4);
        root.left.right.right = new Node(5);
 
        InorderIterator itr = new InorderIterator(root);
        try {
            System.out.print(itr.next().data + " ");
            System.out.print(itr.hasNext() + " ");
            System.out.print(itr.next().data + " ");
            System.out.print(itr.next().data + " ");
            System.out.print(itr.next().data + " ");
            System.out.print(itr.hasNext() + " ");
            System.out.print(itr.next().data + " ");
            System.out.print(itr.next().data + " ");
            System.out.print(itr.hasNext() + " ");
        }
        catch (NoSuchElementException e) {
            System.out.print("No such element Exists");
        }
    }
}


Java
// Java Program for above approach
import java.util.*;
 
// Structure of a Node
class Node {
    int data;
    Node left;
    Node right;
 
    Node(int data)
    {
        this.data = data;
        left = right = null;
    }
}
 
// Inorder Iterator class
class InorderIterator {
    private Node current, rightMost;
 
    InorderIterator(Node root)
    {
        current = root;
        rightMost = null;
    }
 
    public boolean hasNext() { return current != null; }
 
    public Node next()
    {
        if (!hasNext())
            throw new NoSuchElementException();
 
        if (current.left == null) {
            Node temp = current;
            current = current.right;
            return temp;
        }
 
        rightMost = current.left;
 
        while (rightMost.right != null
               && rightMost.right != current)
            rightMost = rightMost.right;
 
        if (rightMost.right == null) {
            rightMost.right = current;
            current = current.left;
        }
 
        else {
            rightMost.right = null;
            Node temp = current;
            current = current.right;
            return temp;
        }
 
        return next();
    }
}
 
class Test {
 
    // Driver Code
    public static void main(String args[])
    {
        Node root = new Node(8);
        root.right = new Node(9);
        root.left = new Node(3);
        root.left.left = new Node(2);
        root.left.right = new Node(4);
        root.left.right.right = new Node(5);
 
        InorderIterator itr = new InorderIterator(root);
        try {
            System.out.print(itr.next().data + " ");
            System.out.print(itr.hasNext() + " ");
            System.out.print(itr.next().data + " ");
            System.out.print(itr.next().data + " ");
            System.out.print(itr.next().data + " ");
            System.out.print(itr.hasNext() + " ");
            System.out.print(itr.next().data + " ");
            System.out.print(itr.next().data + " ");
            System.out.print(itr.hasNext() + " ");
        }
        catch (NoSuchElementException e) {
            System.out.print("No such element Exists");
        }
    }
}



输出
2 true 3 4 5 true 8 9 false 

时间复杂度: O(N),其中 N 是二叉树的节点数。
辅助空间: O(N),堆栈在最坏的情况下将保存所有 N 个元素。

有效的方法:莫里斯遍历可用于使用常数空间解决这个问题。 morris 遍历背后的想法是在一个节点和它的左子树中最右边的节点之间创建一个临时链接,以便可以回溯祖先节点。祖先节点的引用被设置为其左子树中最右边节点的右子节点。

算法:

类被实例化

hasNext()函数

下一个()函数

下面是上述方法的实现。

Java

// Java Program for above approach
import java.util.*;
 
// Structure of a Node
class Node {
    int data;
    Node left;
    Node right;
 
    Node(int data)
    {
        this.data = data;
        left = right = null;
    }
}
 
// Inorder Iterator class
class InorderIterator {
    private Node current, rightMost;
 
    InorderIterator(Node root)
    {
        current = root;
        rightMost = null;
    }
 
    public boolean hasNext() { return current != null; }
 
    public Node next()
    {
        if (!hasNext())
            throw new NoSuchElementException();
 
        if (current.left == null) {
            Node temp = current;
            current = current.right;
            return temp;
        }
 
        rightMost = current.left;
 
        while (rightMost.right != null
               && rightMost.right != current)
            rightMost = rightMost.right;
 
        if (rightMost.right == null) {
            rightMost.right = current;
            current = current.left;
        }
 
        else {
            rightMost.right = null;
            Node temp = current;
            current = current.right;
            return temp;
        }
 
        return next();
    }
}
 
class Test {
 
    // Driver Code
    public static void main(String args[])
    {
        Node root = new Node(8);
        root.right = new Node(9);
        root.left = new Node(3);
        root.left.left = new Node(2);
        root.left.right = new Node(4);
        root.left.right.right = new Node(5);
 
        InorderIterator itr = new InorderIterator(root);
        try {
            System.out.print(itr.next().data + " ");
            System.out.print(itr.hasNext() + " ");
            System.out.print(itr.next().data + " ");
            System.out.print(itr.next().data + " ");
            System.out.print(itr.next().data + " ");
            System.out.print(itr.hasNext() + " ");
            System.out.print(itr.next().data + " ");
            System.out.print(itr.next().data + " ");
            System.out.print(itr.hasNext() + " ");
        }
        catch (NoSuchElementException e) {
            System.out.print("No such element Exists");
        }
    }
}


输出
2 true 3 4 5 true 8 9 false 

时间复杂度: O(N),其中 N 是二叉树中的节点数。虽然我们在创建临时链接,并且多次遍历节点(最多 3 次),但时间复杂度仍然是线性的。
辅助空间: O(1)