题目描述:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。
以下面的二叉搜索树为例:
我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。
解题思路:
考虑对二叉搜索树变成双向链表,二叉搜索树的性质可知,对于每一个根节点其左子树的所有节点都小于根节点,右子树所有节点都大于根节点。而二叉树的中序遍历的结果就是从小到大排列。
考虑根节点4,当中序遍历首先遍历到叶节点1,叶节点1没有子节点,所以其左指针指向空,暂时没有右节点指向它。下一步递归到上一个节点2,并记录下节点1,节点2的左指针指向1,1的右节点指向2,下一步递归到3…
有了这个中序遍历的思想就可以编程实现了。
代码如下:
/*
// 每个节点的定义。
class Node {
public:
int val;
Node* left;
Node* right;
Node() {}
Node(int _val) {
val = _val;
left = NULL;
right = NULL;
}
Node(int _val, Node* _left, Node* _right) {
val = _val;
left = _left;
right = _right;
}
};
*/
class Solution {
public:
Node* treeToDoublyList(Node* root) {
if(root==NULL)return NULL;//如果root是空就返回空
Node* temp=NULL;//定义一个新的空节点,主要是为了记录递归回去的时候方便双指针互相交换。
Convert_Tree(root,temp);
Node *head=NULL,*last=NULL;//定义两个新的节点,找到头节点和为节点。
last=temp;
while(temp->left)temp = temp->left;
head = temp;
head->left = last;
last->right = head;
return head;
}
void Convert_Tree(Node* root,Node* &temp){
if(root==NULL)return;//中序遍历的思想左->操作->右
if(root->left!=NULL)Convert_Tree(root->left,temp);
root->left = temp;//temp记录的是上一步的节点,将此时的根节点左指针指向上一步的节点,初始是NULL因为最小值的左指针一开始就指向NULL,后面就对应每一个上一步的节点。
if(temp!=NULL)temp->right = root;
temp = root;
if(root->right!=NULL)Convert_Tree(root->right,temp);
}
};
注:temp最后的时候肯定是指向没有头尾相连的链表的尾结点,可以动手退一下,后面再根据这个找到头结点,将其首尾相连就可以了。
本文介绍如何利用中序遍历的特性,不创建新节点地将二叉搜索树转换成排序的循环双向链表,通过递归和指针调整实现这一过程。
1258

被折叠的 条评论
为什么被折叠?



