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

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

題目描述

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

/*

思路:將二叉搜尋樹convert為雙向連結串列,嘗試遞迴解決。遞迴關係:當訪問到節點root時,root->left與轉換後的左子樹連結串列完成互指,
root->right與轉換後的右子樹連結串列完成互指。根據題意,令返回值為最左節點,若root存在左子樹,也就是左子樹連結串列的指標,當不存
在左子樹,返回根節點指標。由於返回的指標是最左的,而root->left要指向左子樹連結串列最右的指標,所以連線左子樹連結串列時,要將返回
的指標移到最右。而root->right就是連線右子樹最左指標,可直接連線。
*/
class Solution {
public:
TreeNode*  Convert(TreeNode* pRootOfTree)
{
if (pRootOfTree == NULL)return NULL;
if (pRootOfTree->right != NULL){
pRootOfTree->right = Convert(pRootOfTree->right);
pRootOfTree->right->left = pRootOfTree;
}
if (pRootOfTree->left != NULL){
TreeNode* pmin = Convert(pRootOfTree->left);
TreeNode*pmax = pmin;
while (pmax->right != NULL)pmax = pmax->right;
pRootOfTree->left = pmax;
pRootOfTree->left->right = pRootOfTree;
return pmin;
}
return pRootOfTree;
}
};


/*
中序遍歷思路(建議解法):
中序遍歷對節點的訪問順序和轉換完連結串列從左到右的順序是一樣的。所以在中序遍歷時完成相鄰兩個節點的互指即可。具體做法是把前一個節點記錄下來然後pre->right = cur; cur->left = pre。
*/


class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
if (pRootOfTree == nullptr) return nullptr;
TreeNode* pre = nullptr;
convertHelper(pRootOfTree, pre);
TreeNode* res = pRootOfTree;
while (res->left)
res = res->left;
return res;
}
void convertHelper(TreeNode* cur, TreeNode*& pre)
{
if (cur == nullptr) return;
convertHelper(cur->left, pre);
cur->left = pre;
if (pre) pre->right = cur;
pre = cur;
convertHelper(cur->right, pre);
}
};