一:題目
二:思路
把二叉搜索樹的值升序的打印出來,中序打印即可,但是此題不僅僅是有序的打印出二叉搜索樹的值,而是要將其的結構也改變了,也就是說要改變節點間的指向,讓其成為一個雙向鏈表
我們在中序遍歷的時候,會依次得到4 6 8 10 12 14 16,那我們在依次得到這些節點值的時候,將彼此之間進行鏈接即可
如圖所示:
三:代碼?
class Solution {//中序遍歷 進行鏈接void InOrderConvert(TreeNode* cur,TreeNode*& prev){//cur為空return即可if(cur==nullptr)return;//左子樹遞歸InOrderConvert(cur->left, prev);//對cur和prev的鏈接if(prev!=nullptr)cur->left = prev;if(prev!=nullptr)prev->right = cur;//鏈接完成 cur賦給了prev//cur繼續中序遍歷得到下一個中序節點prev = cur;//右子樹遞歸InOrderConvert(cur->right, prev);}
public:TreeNode* Convert(TreeNode* pRootOfTree) {//二叉搜索樹就是空樹 則返回nullptrif(pRootOfTree==nullptr)return nullptr;//為調用InOrderConvert函數創建參數TreeNode* prev = nullptr;//第一個參數就是根節點 第二個參數是為nullptr的prevInOrderConvert(pRootOfTree, prev);//走到這里 代表雙向鏈表已經完成了TreeNode* head = pRootOfTree;//所以我們要找到雙向鏈表的第一個元素//也就是二叉搜索樹的最小值//即一直遍歷左樹 最后一個節點 即為最小節點while(head->left){head = head->left;}//返回return head;}
};
解釋:
InOrderConvert的參數:
cur:當前正在處理的節點
prev:指向前一個處理過的節點的指針(引用傳遞,以便在遞歸調用間保持更新)
步驟:
遞歸處理左子樹
InOrderConvert(cur->left, prev);
處理當前節點:
將當前節點的左指針(left)指向prev,將prev的右指針(right)指向當前節點,更新prev為當前節點
if(prev!=nullptr)cur->left = prev;if(prev!=nullptr)prev->right = cur;prev = cur;
遞歸處理右子樹
InOrderConvert(cur->right, prev);
解釋:中序遍歷就是左根右,我們想做什么都是在 根 的這個方框里面做的,這道題是鏈接節點,若是按照下圖,則變成了遍歷打印,所以遞歸中序,前序,后序,都只是三個框的順序不同罷了,當然也不要忘記空節點的判斷,遞歸一定需要返回條件的!
這就變成了打印~?