二叉搜索樹與雙向鏈表


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公衆號。
公衆號二維碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章