day17之将二叉搜索树转换成一个排序的双向链表

题目:
输入一棵二叉搜索树,将该二叉搜索树转换为一个排序的双向链表。要求不能创建任何新的节点,只能调整树中指针的指向。
分析与解法:
这里写图片描述
1、由于要求链表是有序的,可以借助二叉树中序遍历,因为中序遍历算法的特点就是从小到大访问结点。当遍历访问到根结点时,假设根结点的左侧已经处理好,只需将根结点与上次访问的最近结点(左子树中最大值结点)的指针连接好即可。进而更新当前链表的最后一个结点指针。
2、由于中序遍历过程正好是转换成链表的过程,即可采用递归处理。
这里写图片描述

节点定义如下:

struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
        val(x), left(NULL), right(NULL) {
        }
};

递归代码实现:

//递归的写法
TreeNode* Convert2(TreeNode* pRootOfTree, TreeNode *&pre, TreeNode *&phead)
{
    if(pRootOfTree == NULL)
        return NULL;

    Convert2(pRootOfTree->left, pre, phead); //左孩子

    if(phead == NULL) //处理链表头
        phead = pRootOfTree; 

    pRootOfTree->left = pre;
    if(pre != NULL)
        pre->right = pRootOfTree; //处理上一个节点的后继。
    pre = pRootOfTree;

    Convert2(pRootOfTree->right, pre, phead); //右孩子

    return phead;
}

TreeNode* Convert2(TreeNode* pRootOfTree)
{
    TreeNode *pre = NULL; //前驱
    TreeNode *phead = NULL; //头节点

    return Convert2(pRootOfTree, pre, phead);
}

非递归实现:

//非递归写法
TreeNode* Convert(TreeNode* pRootOfTree)
{
    TreeNode *pcur = pRootOfTree;
    stack<TreeNode*> s;
    TreeNode *pre = NULL;  //链表的前驱节点
    TreeNode *phead = NULL; //链表的头部
    while(!s.empty()||pcur)
    {
        while(pcur)
        {
            s.push(pcur);
            pcur = pcur->left;
        }

        pcur = s.top(); //拿出最左边的元素
        if(phead == NULL)
            phead = pcur;  //最左边的元素就是链表的头节点。

        pcur->left = pre; //当前节点只能知道它的前驱节点是谁,但是不知道后继节点是谁,所以这里我们用这个节点的前驱去处理前驱节点的后继。
        if(pre != NULL)
            pre->right = pcur; //用这个节点的前驱去处理后继。。。
        pre = pcur;

        s.pop();

        pcur = pcur->right;

    }
    return phead;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值