二叉搜索樹轉換雙向鏈表c++

  • 遞歸版本
    遞歸的思想:
    按照中序遍歷每個節點並加入鏈表更新Plast----將整個樹分解成了無數的小樹,然後將他們分別轉化成了一小段一小段的雙向鏈表,再利用pLast記錄總的鏈表的末尾,然後將這些小段鏈表一個接一個地加到末尾。
class Solution {
public:
    // Plast 節點始終記錄已經加入鏈表的最後一個節點
    TreeNode* Plast = NULL;
    TreeNode* Convert(TreeNode* pRootOfTree){
        if(pRootOfTree == NULL){
            return NULL;
        }
        // Convert 函數始終返回二叉樹轉鏈表後的首節點
        TreeNode* Phead = Convert(pRootOfTree->left);
        //如果左子樹爲空,跟節點爲雙鏈表的頭節點
        if(Phead==NULL){
            Phead = pRootOfTree;
        }
        //將跟節點加入鏈表的最後一個節點
        pRootOfTree->left = Plast;
        if(Plast){
            Plast->right = pRootOfTree;
        }
        Plast = pRootOfTree;
        Convert(pRootOfTree->right);
        return Phead;
    }
};
  • 非遞歸版本
    和中序遍歷非遞歸版本類似,但是要多一個pre記錄當前已加入鏈表的尾節點作爲下一個加入鏈表的left
class Solution {
public:
    TreeNode* Convert(TreeNode* pRootOfTree){
        if(pRootOfTree == NULL){
            return NULL;
        }
        TreeNode* pre = NULL;
        TreeNode* Phead = NULL;
        stack<TreeNode*> s;
        while(!s.empty() || pRootOfTree!=NULL){
            while(pRootOfTree!=NULL){
                s.push(pRootOfTree);
                pRootOfTree = pRootOfTree->left;
            }
            pRootOfTree = s.top();
            s.pop();
            pRootOfTree->left = pre;
            if(pre){
                pre->right = pRootOfTree;
            }
            else{
                Phead = pRootOfTree;
            }
            pre = pRootOfTree;
            pRootOfTree = pRootOfTree->right;
        }
        return Phead;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章