题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};解题思路:
简单的来讲,可以考虑成相当于是先找到二叉树的中序排列,然后将这个排列的顺序从前往后串为一个双向链表即可!
方案一:
跟着这种思路,可以得到第一种解决方案,借助额外空间O(n)。
vector<TreeNode*> mvTree;
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(pRootOfTree==NULL)
return NULL;
InorderTrans(pRootOfTree);
if(mvTree.size()==1)
return pRootOfTree;
for(int i=0;i<mvTree.size();i++) //遍历中序遍历,然后串成链表
{
if(!i)
{
mvTree[0]->left = NULL;
mvTree[0]->right = mvTree[1];
continue;
}
mvTree[i]->left = mvTree[i-1];
if(i!=mvTree.size()-1)
mvTree[i]->right = mvTree[i+1];
else
mvTree[i]->right = NULL;
}
return mvTree[0];
}
void InorderTrans(TreeNode* pRoot)
{
if(pRoot==NULL)
return;
InorderTrans(pRoot->left);
mvTree.push_back(pRoot); //得到中序遍历
InorderTrans(pRoot->right);
}方案二:
就是按照上面中序的思路,不用先得到中序遍历。而是在中序遍历的同时完成链表改造!!!那么这里的重点就是如何记录链表中最后一个元素的问题了!!!请看下面代码。注意二重指针的使用
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(pRootOfTree==NULL)
return NULL;
TreeNode* LastNodeinList = NULL; //设置一个指针,记录链表中最后一个元素
Trans(pRootOfTree,&LastNodeinList);
while(LastNodeinList!=NULL&&LastNodeinList->left!=NULL) //从后往前,找到链表的头
LastNodeinList = LastNodeinList->left;
return LastNodeinList;
}
//递归版本
void Trans(TreeNode* pRoot,TreeNode **pLast) //注意,一定要使用二维指针。因为我需要改变一维指针的值,只能使用二维指针。
{ //如果有引用就方便多了,但是指针没有引用
if(pRoot==NULL)
return;
Trans(pRoot->left,pLast);
pRoot->left = *pLast; //当前节点的前序指向链表的最后元素 //中序遍历同时需要信息的操作,将当前节点左指针指向链表末尾,链表末尾右指针指向当前指针
if(*pLast!=NULL) //链表最后元素的后续指向当前节点
(*pLast)->right = pRoot;
*pLast = pRoot; //当前节点变为链表最后的元素
Trans(pRoot->right,pLast);
}方案三:
可以看做是方案二的拓展,即不使用递归的方式进行二叉树中序遍历,请看下面代码。
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(pRootOfTree==NULL)
return NULL;
TreeNode* LastNodeinList = NULL;
TreeNode* pNode = pRootOfTree;
stack<TreeNode*> s; //使用栈来模拟递归的调用
while(pNode!=NULL||!s.empty())
{
while(pNode!=NULL)
{
s.push(pNode);
pNode = pNode->left;
}
if(!s.empty())
{
pNode = s.top(); //中序遍历在出栈的时候进行操作
s.pop();
pNode->left = LastNodeinList;
if(LastNodeinList)
LastNodeinList->right = pNode;
LastNodeinList = pNode;
pNode = pNode->right;
}
}
while(LastNodeinList!=NULL&&LastNodeinList->left!=NULL)
LastNodeinList = LastNodeinList->left;
return LastNodeinList;
}
本文介绍如何将二叉搜索树转换为排序的双向链表,提供三种不同的实现方法,包括借助额外空间的方案、中序遍历同时转换链表的方法及非递归的中序遍历实现。

466

被折叠的 条评论
为什么被折叠?



