面试题27:二叉搜索树与双向链表
题目描述:
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
题目分析:
给定一颗二叉搜索树,二叉搜索树有left、right指针分别指向左孩子、右孩子,求返回二叉搜索树转换成的排序好的双向链表的头指针。排好序的双向链表,可以想到中序遍历二叉搜索树就是排好序的。
指向左子树结点的指针修改成指向上一个结点,指向右子树结点的指针修改成指向下一个结点。
思路分析:
主要考察的是中序遍历的递归实现,稍微的变形。
遍历到某个结点A时,前面遍历过的结点已然有序,关键是修改结点A的指针指向,A->left指向前面遍历过的最后一个结点L,L->right=A,再遍历结点A的右子树,中序遍历顺序。
代码如下:
TreeNode *Convert(TreeNode *root) {
if (root == 0)
return 0;
TreeNode *last = 0;
ConvertTree(root, &last);
TreeNode *head = last;
while (head && head->left)
head = head->next;
return head;
}
/* 递归遍历的关键是递归结束的条件, *last指向开始当前遍历前的最后一个结点 */
void ConvertTree(TreeNode *root, TreeNode **last) {
if (root == 0)
return;
TreeNode *cur = root;
/* 如果左子树非空,则遍历左子树 */
if (cur->left)
ConvertTree(cur->left, last);
cur->left = *last;
if (*last)
/* ‘->’优先级高于‘*’ */
(*last)->right = cur;
/* 这一句话可以理解为遍历根结点 */
*last = cur;
/* 如果右子树非空,则遍历右子树 */
if (cur->right)
ConvertTree(cur->right, last);
}