二叉搜索树与双向链表
题目链接
思路
由于双向链表按从小到大的顺序,与二叉搜索树中序遍历(左根右)顺序一致,故直接中序遍历操作二叉树即可。
操作步骤
- 确定头结点:最左边的叶子结点。
- 新建一个head指向头结点
- 记录上一结点pre和当前结点cur
- 遍历时不断更新:
pre.right = cur;
cur.left = pre;
- 遍历的递归步骤:
5-1:确定递归结束的条件(cur === null)
5-2:递归左子树
5-3:处理当前结点
5-4:递归右子树
伪代码
function Convert(pRootOfTree) {
// 新建一个引用变量head,用于指向双向链表头结点
let head = null;
// 新建一个引用变量pre,用于记录上一结点
let pre = null;
// 新建递归方法,中序深度优先搜索,当前结点为参数
function MediumOrderDFS(cur) {
// 遍历左子树
MediumOrderDFS(cur.left);
// 操作当前结点
1.确定递归结束的条件和头结点
2.pre的right指向cur
3.cur的left指向pre
4.更新pre为引用当前结点cur
// 遍历右子树
MediumOrderDFS(cur.right);
}
// 将root结点作为参数调用递归函数开始遍历
MediumOrderDFS(pRootOfTree);
// 返回head引用的结点(即最左边的叶子结点)
return head;
}
题解完整代码
那么理解伪代码的运行原理后补充代码完整即可,如下:
/* function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
} */
function Convert(pRootOfTree)
{
let head = null;
let pre = null;
function MediumOrderDFS (cur) {
if(cur === null) {
return;
}
// 递归左结点
MediumOrderDFS(cur.left);
// 处理当前结点
if(pre === null) {
head = cur;
} else {
pre.right = cur;
}
cur.left = pre;
pre = cur;
// 遍历右结点
MediumOrderDFS(cur.right);
}
MediumOrderDFS(pRootOfTree);
return head;
}
module.exports = {
Convert : Convert
};