【问题标题】:Traversing the Binary Search Tree遍历二叉搜索树
【发布时间】:2012-01-25 08:06:29
【问题描述】:

我在阅读Introduction to algorithms 时遇到了这个关于在不使用堆栈或递归的情况下对二叉搜索树进行中序遍历的问题。提示说假设测试相等的指针是合法的操作。我一直在寻找解决这个问题的方法。请给我一些方向。我不是在寻找代码。请给我正确的方向。

完全重复的here

【问题讨论】:

  • 也许不是骗子,在这里 OP 要求按顺序排列,而不是 BFS。我撤销了我的声明。
  • 感谢您的链接。同一本书中还有另一个问题,它要求仅使用 O(1) 额外空间来遍历二叉树。
  • 可能这一切都取决于树的表示。是否在某处提到了您为节点存储的确切链接。如果您存储父节点,您将能够返回您的方式(如果您执行普通的while,您将无法考虑的唯一操作)。如果不存储父节点,就会松散树的结构,无法深入树中。
  • perlmonks.org/?node_id=600456 这在这里被证明是有用的。

标签: algorithm data-structures binary-search-tree


【解决方案1】:

没有堆栈也没有递归意味着你必须使用指针。没有给你代码也没有确切的答案,因为你要求不要:)

想想如何在不使用递归的情况下探索树:你需要做什么?您需要保留哪些指针?树节点可以有指向父节点的指针吗?

希望对你有帮助。

【讨论】:

【解决方案2】:

我们需要一个线程二叉树来进行无递归/堆栈的有序遍历。 Wiki 说“通过使通常为空的所有右子指针指向该节点的中序后继节点,以及所有通常为空的左子指针指向该节点的中序前驱节点,从而对二叉树进行线程化”

所以你得到了一个普通的二叉树,将它转换成一个线程二叉树,这可以使用 Morris Traversal 来完成。 您在 Morris Traversal 中要做的是将每个节点与其有序的后继节点连接起来。所以在访问一个节点时,搜索它的有序前任并让它成为Pred。 然后制作 Pred->right=Current 节点,我们也必须恢复更改。你最好参考这个http://www.geeksforgeeks.org/archives/6358 以获得很好的解释。

【讨论】:

    【解决方案3】:

    您好 Parminder 我已经在 java 中实现了您的问题。请检查一次

    class InorderWithoutRecursion {
        public static void morrisTraversal(TreeNode root) {
    
            TreeNode current,pre;
    
        if(root == null)
            return; 
    
        current = root;
        while(current != null){
            if(current.left == null){
                System.out.println(current.data);
                current = current.right;
            }
            else {
          /* Find the inorder predecessor of current */
                pre = current.left;
                while(pre.right != null && pre.right != current)
                pre = pre.right;
    
          /* Make current as right child of its inorder predecessor */
            if(pre.right == null){
                pre.right = current;
                current = current.left;
            }
    
          /* Revert the changes made in if part to restore the original
            tree i.e., fix the right child of predecssor */
            else {
                pre.right = null;
                System.out.println(current.data);
                current = current.right;
            }
          } 
      } 
    }
     public static void main(String[] args) {
            int[] nodes_flattened = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
            TreeNode root = TreeNode.createMinimalBST(nodes_flattened);
            morrisTraversal(root);
        }
    }
    

    对于 TreeNode 类,下面的代码会帮助你..

    public class TreeNode {
        public int data;      
        public TreeNode left;    
        public TreeNode right; 
        public TreeNode parent;
    
        public TreeNode(int d) {
            data = d;
        }
    
        public void setLeftChild(TreeNode left) {
            this.left = left;
            if (left != null) {
                left.parent = this;
            }
        }
    
        public void setRightChild(TreeNode right) {
            this.right = right;
            if (right != null) {
                right.parent = this;
            }
        }
    
        public void insertInOrder(int d) {
            if (d <= data) {
                if (left == null) {
                    setLeftChild(new TreeNode(d));
                } else {
                    left.insertInOrder(d);
                }
            } else {
                if (right == null) {
                    setRightChild(new TreeNode(d));
                } else {
                    right.insertInOrder(d);
                }
            }
        }
    
        public boolean isBST() {
            if (left != null) {
                if (data < left.data || !left.isBST()) {
                    return false;
                }
            }
    
            if (right != null) {
                if (data >= right.data || !right.isBST()) {
                    return false;
                }
            }       
    
            return true;
        }
    
        public int height() {
            int leftHeight = left != null ? left.height() : 0;
            int rightHeight = right != null ? right.height() : 0;
            return 1 + Math.max(leftHeight, rightHeight);
        }
    
        public TreeNode find(int d) {
            if (d == data) {
                return this;
            } else if (d <= data) {
                return left != null ? left.find(d) : null;
            } else if (d > data) {
                return right != null ? right.find(d) : null;
            }
            return null;
        }
    
        private static TreeNode createMinimalBST(int arr[], int start, int end){
            if (end < start) {
                return null;
            }
            int mid = (start + end) / 2;
            TreeNode n = new TreeNode(arr[mid]);
            n.setLeftChild(createMinimalBST(arr, start, mid - 1));
            n.setRightChild(createMinimalBST(arr, mid + 1, end));
            return n;
        }
    
        public static TreeNode createMinimalBST(int array[]) {
            return createMinimalBST(array, 0, array.length - 1);
        }
    }
    

    【讨论】:

    • 感谢@venkat 下面是我写的伪代码的链接,我认为可能是正确的。 codepad.org/61KQNYKy 这个不使用线程二叉树。
    • 你好 Parminder 检查这个link
    • 你好文卡特。这基本上是我试图实现的,但这当然是一个更优雅的写法。感谢您的链接。
    猜你喜欢
    • 1970-01-01
    • 2019-04-09
    • 2011-09-08
    • 1970-01-01
    • 1970-01-01
    • 2018-02-25
    相关资源
    最近更新 更多