一:题目
二:思路
把二叉搜索树的值升序的打印出来,中序打印即可,但是此题不仅仅是有序的打印出二叉搜索树的值,而是要将其的结构也改变了,也就是说要改变节点间的指向,让其成为一个双向链表
我们在中序遍历的时候,会依次得到4 6 8 10 12 14 16,那我们在依次得到这些节点值的时候,将彼此之间进行链接即可
如图所示:
三:代码
class Solution {//中序遍历 进行链接void InOrderConvert(TreeNode* cur,TreeNode*& prev){//cur为空return即可if(cur==nullptr)return;//左子树递归InOrderConvert(cur->left, prev);//对cur和prev的链接if(prev!=nullptr)cur->left = prev;if(prev!=nullptr)prev->right = cur;//链接完成 cur赋给了prev//cur继续中序遍历得到下一个中序节点prev = cur;//右子树递归InOrderConvert(cur->right, prev);}
public:TreeNode* Convert(TreeNode* pRootOfTree) {//二叉搜索树就是空树 则返回nullptrif(pRootOfTree==nullptr)return nullptr;//为调用InOrderConvert函数创建参数TreeNode* prev = nullptr;//第一个参数就是根节点 第二个参数是为nullptr的prevInOrderConvert(pRootOfTree, prev);//走到这里 代表双向链表已经完成了TreeNode* head = pRootOfTree;//所以我们要找到双向链表的第一个元素//也就是二叉搜索树的最小值//即一直遍历左树 最后一个节点 即为最小节点while(head->left){head = head->left;}//返回return head;}
};
解释:
InOrderConvert的参数:
cur:当前正在处理的节点
prev:指向前一个处理过的节点的指针(引用传递,以便在递归调用间保持更新)
步骤:
递归处理左子树
InOrderConvert(cur->left, prev);
处理当前节点:
将当前节点的左指针(left)指向prev,将prev的右指针(right)指向当前节点,更新prev为当前节点
if(prev!=nullptr)cur->left = prev;if(prev!=nullptr)prev->right = cur;prev = cur;
递归处理右子树
InOrderConvert(cur->right, prev);
解释:中序遍历就是左根右,我们想做什么都是在 根 的这个方框里面做的,这道题是链接节点,若是按照下图,则变成了遍历打印,所以递归中序,前序,后序,都只是三个框的顺序不同罢了,当然也不要忘记空节点的判断,递归一定需要返回条件的!
这就变成了打印~