1. 程式人生 > >劍指36:二叉搜尋樹與雙向連結串列

劍指36:二叉搜尋樹與雙向連結串列

輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。

中序遍歷+遞迴+始終傳遞上一個節點,涉及修改需要採用XX* Name(XX*__ )這種形式或者void Name(XX**)這種形式                

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    TreeNode* Link(TreeNode* cur,TreeNode*last){
        if(cur){
            if(cur->left)
                last = Link(cur->left,last);
            cur->left = last;
            if(last)
                last->right = cur;
            last = cur;
            if(cur->right)
                last = Link(cur->right,last);
        }
        return last;//邏輯上的上一個 ,也是遞迴結束後雙鏈的最後一個
     }
    TreeNode* Convert(TreeNode* pRootOfTree)
    {
        TreeNode* plast = nullptr;
        plast = Link(pRootOfTree,plast);
        while(plast&&plast->left){
            plast = plast->left;
        }
        return plast; 
    }
};

中序遍歷+非遞迴 用棧 +.........


/*
非遞迴中序遍歷,加個指標pre記錄上一次出棧值
*/
class Solution {
public:
    TreeNode* Convert(TreeNode* pRootOfTree)
    {
        TreeNode *head = NULL, *pre = NULL;//head 輸出,pre記錄上一次出棧值
        stack<TreeNode*> s;
        while (pRootOfTree || !s.empty())
        {
            while (pRootOfTree)
            {
                s.push(pRootOfTree);
                pRootOfTree = pRootOfTree->left;
            }
            if (!s.empty())
            {
                pRootOfTree = s.top();
                s.pop();
                if (pre != NULL)
                {
                    pre->right = pRootOfTree;
                    pRootOfTree->left = pre;
                }
                else//pre為空,表示s第一次出棧,第一次出棧值為最左值,即輸出值
                    {
                    head = pRootOfTree;
                }
                pre = pRootOfTree;
                pRootOfTree = pRootOfTree->right;
            }
        }
        return head;
    }
};