【剑指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;
        
        
        
    }
};
画个图,手动走一边流程
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章