输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
来源:互联网 发布:esi数据库检索入口 编辑:程序博客网 时间:2024/05/22 00:15
慕课讨论区里的大神答案很牛,不过是java的代码,我后面贴上自己方法二的c++代码
讲一点递归的心得:递归是个整体工程,需要做好:1)处理好递归的最后一层,或者说极端情况。2)调用递归函数时,要搞清楚函数的参数和返回值。3)把函数本身当做递归的一层来写。
链接:https://www.nowcoder.com/questionTerminal/947f6eb80d944a84850b0538bf0ec3a5
来源:牛客网方法一:非递归版
解题思路:
1
.核心是中序遍历的非递归算法。
2
.修改当前遍历节点与前一遍历节点的指针指向。
import
java.util.Stack;
public
TreeNode ConvertBSTToBiList(TreeNode root) {
if
(root==
null
)
return
null
;
Stack<TreeNode> stack =
new
Stack<TreeNode>();
TreeNode p = root;
TreeNode pre =
null
;
// 用于保存中序遍历序列的上一节点
boolean
isFirst =
true
;
while
(p!=
null
||!stack.isEmpty()){
while
(p!=
null
){
stack.push(p);
p = p.left;
}
p = stack.pop();
if
(isFirst){
root = p;
// 将中序遍历序列中的第一个节点记为root
pre = root;
isFirst =
false
;
}
else
{
pre.right = p;
p.left = pre;
pre = p;
}
p = p.right;
}
return
root;
}
方法二:递归版
解题思路:
1
.将左子树构造成双链表,并返回链表头节点。
2
.定位至左子树双链表最后一个节点。
3
.如果左子树链表不为空的话,将当前root追加到左子树链表。
4
.将右子树构造成双链表,并返回链表头节点。
5
.如果右子树链表不为空的话,将该链表追加到root节点之后。
6
.根据左子树链表是否为空确定返回的节点。
public
TreeNode Convert(TreeNode root) {
if
(root==
null
)
return
null
;
if
(root.left==
null
&&root.right==
null
)
return
root;
// 1.将左子树构造成双链表,并返回链表头节点
TreeNode left = Convert(root.left);
TreeNode p = left;
// 2.定位至左子树双链表最后一个节点
while
(p!=
null
&&p.right!=
null
){
p = p.right;
}
// 3.如果左子树链表不为空的话,将当前root追加到左子树链表
if
(left!=
null
){
p.right = root;
root.left = p;
}
// 4.将右子树构造成双链表,并返回链表头节点
TreeNode right = Convert(root.right);
// 5.如果右子树链表不为空的话,将该链表追加到root节点之后
if
(right!=
null
){
right.left = root;
root.right = right;
}
return
left!=
null
?left:root;
}
方法三:改进递归版
解题思路:
思路与方法二中的递归版一致,仅对第
2
点中的定位作了修改,新增一个全局变量记录左子树的最后一个节点。
// 记录子树链表的最后一个节点,终结点只可能为只含左子树的非叶节点与叶节点
protected
TreeNodeleftLast =
null
;
public
TreeNode Convert(TreeNode root) {
if
(root==
null
)
return
null
;
if
(root.left==
null
&&root.right==
null
){
leftLast= root;
// 最后的一个节点可能为最右侧的叶节点
return
root;
}
// 1.将左子树构造成双链表,并返回链表头节点
TreeNode left = Convert(root.left);
// 3.如果左子树链表不为空的话,将当前root追加到左子树链表
if
(left!=
null
){
leftLast.right = root;
root.left = leftLast;
}
leftLast= root;
// 当根节点只含左子树时,则该根节点为最后一个节点
// 4.将右子树构造成双链表,并返回链表头节点
TreeNode right = Convert(root.right);
// 5.如果右子树链表不为空的话,将该链表追加到root节点之后
if
(right!=
null
){
right.left = root;
root.right = right;
}
return
left!=
null
?left:root;
}
这里我贴一下自己方法二的C++代码
/*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; if(pRootOfTree->left == NULL && pRootOfTree->right == NULL) return pRootOfTree; // 1.将左子树构造成双链表,并返回链表头节点 TreeNode* left = Convert(pRootOfTree->left); TreeNode* p = left; // 2.定位至左子树双链表最后一个节点 while(p!=NULL && p->right!=NULL){ p = p->right; } // 3.如果左子树链表不为空的话,将当前root追加到左子树链表 if(left!=NULL){ p->right = pRootOfTree; pRootOfTree->left = p; } // 4.将右子树构造成双链表,并返回链表头节点 TreeNode *right = Convert(pRootOfTree->right); // 5.如果右子树链表不为空的话,将该链表追加到root节点之后 if(right!=NULL){ right->left = pRootOfTree; pRootOfTree->right = right; } return left!=NULL?left:pRootOfTree; }};
阅读全文
0 0
- java 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
- 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向
- (Java实现)输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向
- 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
- 牛客原题 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
- 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
- 题目:将二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向
- 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。
- 输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表
- 将一颗搜索树转换成一个排序的双向链表。要求不能创建任何新的节点
- 将二叉搜索树转换为双向链表(不创建新的结点)&&数组中出现超过一半的数字
- 【二叉树】将二叉搜索树转换成一个排序的双向链表
- 二叉树--将二叉搜索树转换成一个排序的双向链表
- 剑指offer27---将二叉搜索树转换成一个排序的双向链表
- 将二叉搜索树转换成一个排序的双向链表
- 将二叉搜索树转换成一个排序的双向链表
- day17之将二叉搜索树转换成一个排序的双向链表
- 将二叉搜索树转换成一个排序的双向链表
- 分析zookeeper能做什么
- Android中自定义LayoutInflater.Factory实现全局替换系统控件(比如TextView,EditText等)
- MS贝叶斯分析算法
- CSDN博客插入图片
- 只遍历链表一次求链表中间结点
- 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
- SQLServer 链接失败
- 关于卷积的一个血腥的讲解,看完给跪了
- MS时序分析算法
- 共用体和结构体所占内存大小的计算方法一
- POJ 2492 A Bug's Life (并查集加强版)
- GitHub入门(5)团队协同工作
- Promise+ajax && async+await+promise+ajax
- 遍历本驱动设备链 (附加)设备栈上的设备 信息