题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
在二叉搜索树中,每个结点都有两个分别指向其左、右子树的指针,左子树结点的值总是小于父结点的值,右子树结点的值总是大于父结点的值。而在双向链表中,每个结点也有两个指针,它们分别指向前一个结点和后一个结点。所以这两种数据结构的结点是一致,二叉搜索树之所以为二叉搜索树,双向链表之所以为双向链表,只是因为两个指针的指向不同而已,通过改变其指针的指向来实现是完全可能的。
例如如下的二叉搜索树,
若采用中序遍历,其遍历顺序为1-2-3-4-5-6-7,通过适当的指针变换操作,可变成的双向有序链表如下:
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(pRootOfTree == nullptr) return nullptr;
TreeNode* pre = nullptr;
convertHelper(pRootOfTree, pre);
TreeNode* res = pRootOfTree;
while(res ->left)
res = res ->left;
return res;
}
void convertHelper(TreeNode* cur, TreeNode*& pre)
{
if(cur == nullptr) return;
convertHelper(cur ->left, pre);
cur ->left = pre;
if(pre) pre ->right = cur;
pre = cur;
convertHelper(cur ->right, pre);
}
};
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
if (pRootOfTree == NULL)return NULL;
TreeNode *pointer = NULL;
convert2List(pRootOfTree, pointer);
while (pointer->left!=NULL)
{
pointer = pointer->left;
}
return pointer;
}
void convert2List(TreeNode* pRoot,TreeNode *&pointer)
{
if (pRoot == NULL)
{
return;
}
{
if (pRoot->left != NULL)
{
convert2List(pRoot->left,pointer);
}
pRoot->left = pointer;
if (pointer != NULL)
{
pointer->right = pRoot;
}
pointer = pRoot;
if (pRoot->right!=NULL)
{
convert2List(pRoot->right, pointer);
}
}
}
};
可以中序遍历,然后push到一个vector里面,再连接成链表,此方法可以实现,但是违反题目不能创建新空间的规定,属于犯规作弊
class Solution {
public:
vector<TreeNode*> nodes;
void tranverse(TreeNode* pRoot) {
if (nullptr == pRoot)
return;
tranverse(pRoot->left);
nodes.push_back(pRoot);
tranverse(pRoot->right);
}
TreeNode* adjustTree() {
for (int i = 0; i < nodes.size() - 1; ++i)
nodes[i]->right = nodes[i+1];
nodes[nodes.size()-1]->right = nullptr;
for (int i = nodes.size() - 1; i > 0; --i)
nodes[i]->left = nodes[i-1];
nodes[0]->left = nullptr;
return nodes[0];
}
TreeNode* Convert(TreeNode* pRoot)
{
if (nullptr == pRoot)
return nullptr;
tranverse(pRoot);
return adjustTree();
}
};
非递归中序遍历
void inOrder2(BinTree *root) //非递归中序遍历
{
stack<BinTree*> s;
BinTree *p=root;
while(p!=NULL||!s.empty())
{
while(p!=NULL)
{
s.push(p);
p=p->lchild;
}
if(!s.empty())
{
p=s.top();
cout<<p->data<<" ";
s.pop();
p=p->rchild;
}
}
}
/*
非递归中序遍历,加个指针pre记录上一次出栈值
*/
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
TreeNode *head = NULL, *pre = NULL;//head 输出,pre记录上一次出栈值
stack<TreeNode*> s;
while (pRootOfTree || !s.empty())
{
while (pRootOfTree)
{
s.push(pRootOfTree);
pRootOfTree = pRootOfTree->left;
}
if (!s.empty())
{
pRootOfTree = s.top();
s.pop();
if (pre != NULL)
{
pre->right = pRootOfTree;
pRootOfTree->left = pre;
}
else//pre为空,表示s第一次出栈,第一次出栈值为最左值,即输出值
{
head = pRootOfTree;
}
pre = pRootOfTree;
pRootOfTree = pRootOfTree->right;
}
}
return head;
}
};