输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
在搜索二叉树中,左子结点的值总是小于父结点的值,右子结点的值总是大于父结点的值。因此我们在转换成排序双向链表时,原先指向左子结点的指针调整为链表中指向前一个结点的指针,原先指向右子结点的指针调整为链表中指向后一个结点指针。
因为要遍历树,所以要选取遍历算法。为了保证遍历的有序性,采用中序遍历。在 convertNode 函数实现中,注意 lastNodeInList 语意,剩下的按照思路写出来即可。
class TreeNode {constructor(value, left = null, right = null) {this.value = value;this.left = left;this.right = right;}}/*** 将node和左右子树转化为双向链表* @param {TreeNode} node 待转化的节点* @param {TreeNode} lastNodeInList 已转换好的双向链表的尾结点*/function convertNode(node, lastNodeInList = null) {if (!node) {return null;}// 先处理左子树if (node.left) {lastNodeInList = convertNode(node.left, lastNodeInList);}// 将当前节点与原双向链表拼接node.left = lastNodeInList;if (lastNodeInList) {lastNodeInList.right = node;}// 处理右子树lastNodeInList = node;if (node.right) {lastNodeInList = convertNode(node.right, lastNodeInList);}// 返回新链表的尾节点return lastNodeInList;}/**** @param {TreeNode} root*/function convertTreeToList(root) {let lastNodeInList = convertNode(root);let headOfList = lastNodeInList;// 返回转化好的双向链表的头节点while (headOfList && headOfList.left) {headOfList = headOfList.left;}return headOfList;}/*** 测试代码*/const root = new TreeNode(10,new TreeNode(6, new TreeNode(4), new TreeNode(8)),new TreeNode(14, new TreeNode(12), new TreeNode(16)));let nodeOfList = convertTreeToList(root);while (nodeOfList) {console.log(nodeOfList.value);nodeOfList = nodeOfList.right;}