title: 2019-8-23 二叉搜索樹與雙向鏈表
tags: 算法,每日一題,二叉樹,鏈表
二叉搜索樹與雙向鏈表
1. 題目描述
輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能創建任何新的結點,只能調整樹中結點指針的指向。
2.題目解析
二叉搜索樹的中序遍歷就是一個排好順序的序列,所以關鍵是對二叉搜索樹的中序遍歷前後的節點進行重新連接。這裏連接的方式爲節點的right指向下一個節點,left指向上一個節點。
2.1 思路解析
這裏有兩種方式來對中序遍歷進行重新連接。
方案一:使用一個vector保存遍歷的結果,然後將vector中的元素前後相連組成一個雙向鏈表。
方案二:只在在進行中序遍歷時就進行重新連接,主要就是要記錄當前節點之前的節點是哪一個。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(pRootOfTree == NULL || (pRootOfTree->left == NULL && pRootOfTree->right == NULL)) return pRootOfTree;
return Convert2(pRootOfTree);
}
//right指向下一個節點,left指向上一個節點
TreeNode* Convert1(TreeNode* pRootOfTree){//方法一:使用一個vector保存二叉搜索樹的中序遍歷結果
stack<TreeNode*> help_stack;
TreeNode* head = pRootOfTree;
vector<TreeNode*> res;
while( head != NULL || !help_stack.empty()){
if(head != NULL){
help_stack.push(head);
head = head->left;
}else{
head = help_stack.top(); help_stack.pop();
res.push_back(head);
head = head->right;
}
}
res[0]->left = NULL;
for(int i=0; i<res.size()-1; ++i){
res[i]->right = res[i+1];
res[i+1]->left = res[i];
}
res[res.size()-1]->left = res[res.size()-2];
res[res.size()-1]->right = NULL;
return res[0];
}
TreeNode* Convert2(TreeNode* pRootOfTree){//方法二:使用記錄的方式
stack<TreeNode*> help_stack;
TreeNode* new_head = NULL;
TreeNode* head = pRootOfTree;
TreeNode* pre = NULL;
while(head != NULL || !help_stack.empty()){
if(head != NULL){
help_stack.push(head);
head = head->left;
}else{
head = help_stack.top(); help_stack.pop();
if(new_head == NULL) new_head = head;//新的鏈表的頭
//構建雙鏈表
head->left = pre;
if(pre) pre->right = head;
pre = head;
head = head->right;
}
}
return new_head;
}
};
更多關於編程和機器學習資料請關注FlyAI公衆號。