簡體   English   中英

二叉樹和特殊節點打印

[英]Binary tree and especial node printing

我有一棵這樣的樹,用二進制表示;

                 1
                /
               2
                \
                 3
                / \
               6   4
                \   \
                 7   5
                    /
                   8
                  /
                 9
                  \
                   10
                     \
                      11

但實際上這不是二叉樹,而是

     1
  / | | \
 2  3 4 5
    /\  |
    6 7 8
       /| \
      9 10 11

您能幫我打印出類似的內容嗎(子級打印順序相反)

1 : 5 4 3 2
5 : 8
3 : 7 6
8 : 11 10 9

我的TNode類看起來像。

class TNode {
public:
    unsigned long int data;
    TNode * left;///first child
    TNode * right;/// sibling
    TNode * parent;/// parent

    TNode(unsigned long int d = 0, TNode * p = NULL, TNode * n = NULL)///konstruktors
    {
        left = NULL;
        right = NULL;
        parent = p;
        data = d;
    }
};

這需要堆棧實現嗎?

嘗試類似的方法:(尚未測試)

printTree(TNode root) {
    queue <TNode> proc;
    proc.push(root);
    while (!proc.empty()) {
        TNode front = proc.front();
        proc.pop();

        // add front's children to a stack
        stack <Tnode> temp;
        Tnode current = front->left;
        while (current != NULL) {
            temp.push(current);
            current = current->right;
        }
        // add the children to the back of queue in reverse order using the stack.
        // at the same time, print.
        printf ("%lld:", front->data);
        while (!temp.empty()) {
            proc.push(temp.top());
            printf(" %lld", temp.top()->data);
            temp.pop();
        }
        printf("\n");
    }

}

我仍在嘗試使其更優雅。 感謝您提出有趣的問題!

編輯:將格式說明符更改為lld

這種方法怎么樣:以預定順序遍歷樹(訪問每個節點)。 對於每個節點(前往時),檢查其是否有左子節點。 如果是這樣(表示原始樹中具有子元素的節點),則用“:”打印節點數據,並獲取其子樹並遞歸跟隨所有正確的兒子(代表所有同級兄弟),然后打印每個正確的兒子數據(您有)以相反的順序在代碼中:

void print_siblings() {
    if (this->right != NULL) {
        this->right->print_siblings();
    }
    cout << data << ", ";
}

void traverse(void) {
    if (this->left != NULL) {
        cout << data << ":";
        this->left->print_siblings();
        cout << endl;
        this->left->traverse();
    }

    if (this->right != NULL) {
        this->right->traverse();
    }
}

編輯:這是一個有序遍歷:

void traverse_inorder(void) {
    if (this->left != NULL) {
        this->left->traverse_inorder();
        cout << data << ":";
        this->left->print_siblings();
        cout << endl;
    }

    if (this->right != NULL) {
        this->right->traverse_inorder();
    }
}

預購的輸出為:

1:5, 4, 3, 2,
3:7, 6,
5:8,
8:11, 10, 9,

訂單的輸出將是:

3:7, 6,
8:11, 10, 9,
5:8,
1:5, 4, 3, 2,

Edit2:為了完整起見,還需要后遍歷:-)

void traverse_postorder(void) {
    if (this->left != NULL) {
        this->left->traverse_postorder();
    }

    if (this->right != NULL) {
        this->right->traverse_postorder();
    }
    if (this->left != NULL) {
        cout << data << ":";
        this->left->print_siblings();
        cout << endl;
    }

}

及其輸出:

8:11, 10, 9,
5:8,
3:7, 6,
1:5, 4, 3, 2,

我做了這樣的事情,但是由於while循環,這有點不遞歸。 有什么辦法讓它更REC

void mirrorChilds(TNode * root)//
{
    if(!root) return;
    cout << root->data << " ";
    //tmp = tmp->right;
    if(!root->left) return;
    TNode * tmp = root->left;
    while(tmp != NULL)
    {

        root->left = tmp;
        tmp = tmp->right;
    }

   tmp = root->left;
   while(root != tmp)
    {
        cout << tmp->data << " ";
        tmp = tmp->parent;

    }
    cout << endl;
    tmp = root->left;
    while(root != tmp)
    {
        if(tmp->left) mirrorChilds(tmp);
        //if(tmp->left) cout << tmp->left->data << endl;
        tmp = tmp->parent;

    }
}

它完全可以正常工作,但是,我有點想獲得O(n * log(n))時間...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM