剑指OFFER题32------按牛客网通过率排序
时间:2018.12.26.2012
作者:Waitt
题目
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
时间限制:1秒 空间限制:32768K 热度指数:186423
解答
由于是二叉搜索树转有序的双向链表,因此考虑利用中序遍历进行迭代或循环
多创建一个结点,该结点指向中序遍历时的前一个结点,也可认为指向有序链表的前一个结点
迭代法
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
//中序遍历函数,pre为中序遍历时的上一个结点,必须为地址的引用,因为在迭代过程中,pre必须实时变化!
void zhong(TreeNode* pp,TreeNode* &pre)
{
if(!pp)//迭代终止条件
return;
zhong(pp->left,pre);//左子树迭代
pp->left=pre;//当前结点左指针指向其上一个结点
if(pre)//若上一个结点存在,则上一个结点的右指针指向本结点
pre->right=pp;
pre=pp;//上一个结点指向本结点
zhong(pp->right,pre);//右子树迭代
}
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(!pRootOfTree)
return pRootOfTree;
TreeNode* pre=NULL;
zhong(pRootOfTree,pre);
pre=pRootOfTree;
while(pre->left)//寻找头结点
{
pre=pre->left;
}
return pre;
}
};
循环法
中序遍历循环,先序遍历以及后续遍历循环参考:http://www.cnblogs.com/bjwu/p/9284534.html
/*
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)
return pRootOfTree;
stack<TreeNode*> a;//用辅助栈实现
TreeNode* pre=NULL;
TreeNode* pp=pRootOfTree;
a.push(pp);
pp=pp->left;
while(pp||a.size())
//判断条件必须这么些,在循环过程中,极有可能出现栈刚好为空,而还有未入栈的结点的情况
{
while(pp)//每次寻找该结点的所有左子树
{
a.push(pp);
pp=pp->left;
}
a.top()->left=pre;
if(pre)
pre->right=a.top();
pre=a.top();
a.pop();
if(pre->right)
pp=pre->right;
}
pre=pRootOfTree;
while(pre->left)
pre=pre->left;
return pre;
}
};
迭代法要远比循环法容易实现的多,而且更好理解。但是多掌握一种方法也不为坏事