二叉搜索树与双向链表

来源:互联网 发布:第二次工业革命 知乎 编辑:程序博客网 时间:2024/06/13 23:59

题目描述:

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

解题思路:

二叉搜索树的左子结点的值总是小于父结点的值,右子结点的值总是大于父结点的值。因此我们在转换成排序双向链表时,原先指向左子结点的指针调整为链表中指向前一结点的指针,原先指向右子结点的指针调整为链表中指向后一个结点指针。二叉搜索树的中序遍历属于非降序列,所以先一路向左,寻找左子树中最小的节点,作为链表的头结点,也暂时作为当前节点的上一节点plast,然后继续遍历,当前节点的值大于上一节点,所以current->left=plast;

plast->right=current;一直循环知道遍历完整个二叉搜索树及此时的栈为空。

在这使用的是中序遍历的非递归版本。

C++实现代码:

/*struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;TreeNode(int x) :val(x), left(NULL), right(NULL) {}};*/class Solution {public:    static void goAlongLeftBranch(TreeNode* pRootOfTree,stack<TreeNode*> &s)    {        while(pRootOfTree)        {            s.push(pRootOfTree);            pRootOfTree=pRootOfTree->left;        }    }    TreeNode* Convert(TreeNode* pRootOfTree)    {        stack<TreeNode*> s;        TreeNode* current=pRootOfTree; //当前节点        TreeNode* phead=NULL; //链表的头结点        TreeNode* plast=NULL; //当前节点的上一节点        while(current!=NULL||!s.empty())        {            goAlongLeftBranch(current,s);            if(!s.empty())            {                current=s.top();                s.pop();                if(plast!=NULL) //说明不是链表的头结点                {                    plast->right=current;                    current->left=plast;                }                else //链表的头结点                {                    phead=current;                }            }            plast=current;            current=current->right;        }        return phead;    }};