0

Today, I learnt 3 DFS(Depth First Search) traversals for rooted trees i.e., In-order, Pre-order & Post-order traversals.

For instance, If I consider Pre-order traversal,

typedef struct SiblingTreeNode {
    struct SiblingTreeNode *parent;
    void *item;
    struct SiblingTreeNode *firstChild;
    struct SiblingTreeNode *nextSibling;
} Node;

typedef struct LCRSTree {
    Node *root;
    int size;
} Tree;


void preOrderTraverse(Node * node) {
    visit(node);

    if (node->firstChild) {
        printf("\n|");
        preOrderTraverse(node->firstChild);
    }

    if (node->nextSibling) {
        printf("-->");
        preOrderTraverse(node->nextSibling);
    }
}

void preOrder(Tree *tree) {
    preOrderTraverse(tree->root);
}

then nodes are visited in below sequence,

enter image description here

Practically working for NMS(Network management System) applications, We use rooted trees(LCRS representation) to maintain hierarchy of network elements(metrics), where depth of leaf node is pretty huge.

Asymptotically, space complexity of pre-order traversal is O(d), where d is the depth of the lowest leaf.

On applying any of these 3 traversals, there is a great chance for an application to crash, due to stack over flow.

For example - If you consider visiting node sequence(above) call stack is maintained from root to leaf, when you visited 3rd node.

With the given Tree representation above, Without maintaining explicit data structures(like stack), How to optimize the traversal algorithm, on rooted trees?

Note: On construction, Tree looks like this

Stephen Docy
  • 4,738
  • 7
  • 18
  • 31
overexchange
  • 15,768
  • 30
  • 152
  • 347

1 Answers1

2

There is a non-recursive solution for Pre-order traversal, that uses the stack data structure insdead of the call stack in recursive. if memory is still an issue, you can design a stack to offload some of it to storage, and reload it when needed.

void iterativePreorder() {
    TreeNode top;
    if (root == null)
        return;

    Stack<SiblingTreeNode> st = new Stack<SiblingTreeNode>();
    st.push(root);

    while (!st.empty()) {
        top = st.pop();
        //do traversal effect
        if (top.right != null)
            st.push(top.right);
        if (top.left != null)
            st.push(top.left);
    }
}
Ran Koretzki
  • 464
  • 3
  • 15
  • Without explicit stack on heap, Do we have any traversal algo? – overexchange Dec 16 '16 at 09:09
  • Most tree traversals are based on DFS and BFS algorethems. DFS, is stack based and BFS is queue based." I think it would be hard avoiding them, since there is aneed to keep a state of traversals. You can offload some of the stack to storage (HDD, SSD). – Ran Koretzki Dec 16 '16 at 09:33
  • In-order, pre-order & post-order are DFS traversals of rooted tree. How do you perform BFS on rooted tree? – overexchange Dec 16 '16 at 09:45
  • start from the root, ad both children to the queue. While queue not empty, dequeue a node, add it's chidren to the queue and so on. It passes all nodes in a tree, but level by level order. – Ran Koretzki Dec 16 '16 at 09:52
  • hmm Let me try both DFS and BFS iteratively now – overexchange Dec 16 '16 at 10:03