【劍指Offer】:面試題27:二叉搜索樹與雙鏈表

整理自劍指Offer


一:題目描述

輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能創建任何新的結點,只能調整樹中結點指針的指向。


二:代碼實現

在二叉樹中,每個節點都有兩個指向子結點的指針。在雙向鏈表中,每個節點也有兩個指針,他們分別指向前一個結點和後一個節點。

二叉搜索樹中左子結點的值都小於父結點的值,右子節點的值總是大於父子結點的值,如果採用中序遍歷的方式得到的就是排序好的序列。

現在需要解決的就是如何調整指針,使原先指向左子結點的指針調整爲鏈表中指向前一個結點的指針,原先指向右子節點的指針調整爲鏈表指向後一個節點的指針。



三:代碼實現


/*
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)
            return NULL;
        
        stack< TreeNode* > stackOfTree;
        
        TreeNode* pNode=pRootOfTree;//指向要連接到鏈表的二叉搜索樹的結點
        TreeNode* pPre=NULL;//指向雙向鏈表的最後一個結點
        
        bool isFirstNode=true;
        
        
        while(pNode!=NULL || !stackOfTree.empty()){
            //指向以本次while循環R=pNode最左結點,因爲它是當前子樹的最小值
            while(pNode!=NULL){
                stackOfTree.push(pNode);
                pNode=pNode->left;
            }
            //彈棧,彈出最左結點
            pNode=stackOfTree.top();
            stackOfTree.pop();
            
            if(isFirstNode){
                //如果它是鏈表第一個節點創建頭指針
                pRootOfTree=pNode;  //因爲根節點已經壓棧,所以不怕
                pPre=pRootOfTree;
                isFirstNode=false;
            }
            else{
                //如果不是鏈表第一個節點,將當前節點鏈接到鏈表的後面
                //鏈表最後結點的有指針指向當前節點
                pPre->right=pNode;
                //當前節點的左指針指向鏈表最後一個結點
                pNode->left=pPre;
                //pPre指向鏈表最後一個結點
                pPre=pNode;
            }
            
            pNode=pNode->right;
                
        }
        
        pPre->right=NULL;
        
        return pRootOfTree;
        
        
        
    }
};
畫個圖,手動走一邊流程
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章