剑指 Offer 36. 二叉搜索树与双向链表

本文介绍如何利用中序遍历的特性,不创建新节点地将二叉搜索树转换成排序的循环双向链表,通过递归和指针调整实现这一过程。

题目描述:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。

以下面的二叉搜索树为例:
在这里插入图片描述我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。

解题思路:
考虑对二叉搜索树变成双向链表,二叉搜索树的性质可知,对于每一个根节点其左子树的所有节点都小于根节点,右子树所有节点都大于根节点。而二叉树的中序遍历的结果就是从小到大排列。
考虑根节点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最后的时候肯定是指向没有头尾相连的链表的尾结点,可以动手退一下,后面再根据这个找到头结点,将其首尾相连就可以了。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值