2011-03-12 51 views
0

Ii有問題。我必須將它的鋸齒形格式的二叉樹轉換爲雙向鏈表。
將Zigzag順序中的二叉樹轉換爲雙向鏈表

 Given BT: 
       [1] 
      [2]     [3] 
     [4]  [5]   [6]  [7] 
    [8] [9] [10] [11] [12] [13] [14] [15]

ZigZag order of BT in DLL: [1] [3] [2] [4] [5] [6] [7] [15] [14] [13] [12] [11] [10] [9] [8]

這裏是我的僞代碼:

DLLNode* ConvertBTToZigZgDLL(Node* root) 
{ 
    DLLNode* start=createDLLNode(root->data); 
    DLLNode* tail=start; 
    Stack<Node> stack1, stack2; 
    stack1.push(root->left); 
    stack1.push(root->right); 
    while(!stack1.Empty() || !stack2.Empty()) 
    { 
    while(stack1.HasElement()) 
    { 
     Node* temp=stack1.Pop(); 
     stack2.push(temp->right); 
     stack2.push(temp->left); 
     tail=Attach(tail,createDLLNode(temp->data)); 
     tail=tail->next; 
    } 
    while(stack2.HasElement()) 
    { 
     Node* temp=stack2.Pop(); 
     stack1.push(temp->left); 
     stack1.push(temp->right); 
     tail=Attach(tail,createDLLNode(temp->data)); 
     tail=tail->next; 
    } 
    } 
    return start; 

} 這裏TimeComplexity O(N),其中N是沒有在給定的二叉樹中的節點。


    DLLNode* Attach(DLLNode* source, DLLNode* dest) 
    { 
    source.Next=dest; 
    dest.prev=source; 
    return source; 
    } 

    DLLNode* CreateDLLNode(int data) 
    { 
    DLLNode* res=malloc(sizeof(struct DLLNode)); 
    res->data=data; 
    res->prev=NULL; 
    res->next=NULL; 
    return res; 
    }

所有我想知道什麼是錯在我的代碼的邏輯

一個朋友在說上面的代碼無法正常工作和錯誤的。我無法找到任何用例在我的邏輯會失敗(不包括空檢查/空/空節點)

只是檢查我的代碼的邏輯,讓我知道。

我的邏輯很簡單:使用2個堆疊。在堆棧1中,我總是先推動左邊的孩子,然後推進右邊的孩子,在堆棧2中,我總是先推動右邊的孩子,然後再推動孩子第二。最初加載stack1,而stack1是非空pop,並將堆棧2中相應的右/左子節點推入。對於上面的例子,我的堆棧狀態應該像s1-B [2,3] T s2-B [7,6,5,4] T s1-B [8,9,10,11,12,13,14, 15] T型堆疊底部T型堆疊頂部。請再次檢查。謝謝。

+0

我的代碼沒有檢查其他帖子中給出的任何節點的任何級別。我的關注是否我的代碼的上述邏輯是否正確..這個相同的代碼是其他地方..請理解並幫助我..謝謝.. – javasoul 2011-03-12 11:28:12

+0

當試圖詢問一個算法,這對其他人更容易批評你是否用簡單的語言陳述了你想要做什麼(與特定的實現相比) – 2011-03-12 13:14:43

回答

1

算法:

使用修改後的BFS算法,其中一個FIFO隊列,而不是兩個堆疊使用stack1用於包含在那些級別的節點進行訪問從右到左,而stack2包含要被訪問的節點從左到右。

該列表被初始化爲根節點,並且第一級(最接近根)被存儲在stack1。因此,第一次通過stack1將以適當的順序拉第一級。

對於一般情況下的證明,假設stack1中的元素以正確的順序存儲,則從N層的stack1中拉取節點可確保按從右到左的順序處理它們。對於每個如此處理的節點,將子樹存儲在第一個右側的stack2中,然後保留。這保證節點列表檢索stack2級別N + 1有從左到右的順序。當N層沒有更多節點時,while循環完成。此時,從stack2中提取節點將按從左到右的順序從層N + 1中檢索所有節點。相反,當從左到右拉動從stack2開始的節點時,首先將子節點存儲在stack1左邊,然後右邊,確保當它們在下一次迭代中按從右到左的順序被拉出時。

所以基本上算法證明是合理的。現在不能確保實施。特別是你將所有的NULL指針添加到堆棧中,這意味着你將檢索它們,然後嘗試通讀它們。

+0

所有我想要的是我的邏輯工作與否。我在上星期六的採訪/書面測試中給出了這個解決方案..這位面試官說,它從來沒有工作..即使我問人力資源重新評估我的答案,同一個人再次表示它不會工作..他甚至沒有花費超過30秒在我的答案..再次感謝..非常感謝你..我得到了我的信心..謝謝..你們幫助其他開發人員保持精神..謝謝..這個開發人員社區需要你們。 。 謝謝!我很抱歉,我無法爲自己的聲譽添加任何分數,因爲它說我需要分鐘。 15聲望.. – javasoul 2011-03-14 04:28:41

+1

@javasoul:當你編寫代碼,並且你知道你在做什麼時,你應該能夠在幾秒鐘內提供類似於此的證明。我從算法課程中學到的一件事(在此之前我自己研究過算法)是證明是一件好事,因爲它們演示算法或指出解決方案錯誤的地方。當面試官告訴你這是錯誤的,你應該加強並詢問原因,解釋你的推理。在採訪中這通常比算法本身更重要。 – 2011-03-14 08:35:09

+0

是的。你是對的! – javasoul 2011-03-14 09:12:55

1

這已經覆蓋了另一個問題。

this stackoverview set of answers

+0

不關心我的解決方案中的邏輯......我的邏輯是否正確......只有我想知道.. – javasoul 2011-03-12 11:20:45

+1

你可能是相當新的,一般來說,當你只是想表明問題已經被回答時,你應該爲問題添加評論,而不是隻有一個鏈接的答案。一旦你獲得了足夠的聲望,你將能夠*投票結束重複*,但與此同時,它習慣於只添加評論。 – 2011-03-12 13:13:09

+0

在另一篇文章中,回覆沒有給出標準的僞代碼/給定的代碼是以鋸齒形打印樹中的數據 - 不返回任何動態鏈接列表。這也是一個老去年的職位。 – javasoul 2011-03-12 13:55:00