劍指offer——二叉搜尋樹與雙向連結串列C++
阿新 • • 發佈:2020-12-27
技術標籤:劍指Offer樹#連結串列連結串列演算法二叉樹劍指offer
樹的遞迴操作說來說去就這麼幾個,這裡很明顯要用中序,因為要形成的是從小到大的雙向連結串列。BST的中序就是從小到大的。
這裡的中序就難在根那個地方的操作。遞迴函式需要一個指標的引用來作為前一個結點(pre),pre的初值為空指標。遞迴函式先進行左子樹的遞迴,遞迴到最左的結點後,將其left改為pre(這樣你就知道pre的初值為什麼是空指標了,因為最左的結點的left是不可能有數字的)。如果pre不為空,就將pre的right改為當前結點。將pre改為root。我們可以想象pre是指向你自己構建的連結串列的最後一個元素的,它需要更新。然後遞迴右子樹。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
void inOrderTravese(TreeNode* root, TreeNode* &pre){
//傳引用改變pre本身的值,返回此層遞迴後,上一層遞迴要用改變後的pre值
if(root == NULL) return;
//左:
inOrderTravese(root->left,pre);
root->left = pre;
if(pre!=NULL) pre->right = root;
pre = root;
inOrderTravese(root->right,pre);
}
TreeNode* Convert(TreeNode* pRootOfTree)
{
//BST轉化為排序的雙向連結串列,中序遍歷即可
//其實樹的三序遍歷的遞迴思想主要是寫出根那一步的操作
//此題需要一個前驅結點,也就是你自己在構建這條雙向連結串列時當前的最後一個結點
//把你現在在操作的這個結點的left指向前驅結點,把前驅結點的right指向當前結點
//然後更新當前這條連結串列的最後一個節點
if(pRootOfTree == NULL) return NULL;
TreeNode* pre = NULL;
inOrderTravese(pRootOfTree,pre);
TreeNode* res = pRootOfTree;
while(res->left != NULL) res = res->left;
return res;
}
};