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

本文介绍了一种将二叉搜索树转换为排序双向链表的方法,通过递归分解与构造,调整树中节点指针指向实现转换,无需创建新节点。以具体实例演示了整个转换过程,并附带实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

我的想法很简单,分解&递归。从下至上构造,将其化为有序链表。构造过程中,若节点有右孩子,则左旋(或右旋),将右(左)孩子作为父节点的新左孩子,最后父节点连接左右子树(因左子树所有数大小都小于右子树任意节点,所以父节点必然在中间),作为新的左(右)孩子。
我以下面的树做例子讲下思路。
这里写图片描述

第一次分解

首先判断root是否是NULL,不为NULL,则递归分解。
递归的结果会将其分解为两个子树:
这里写图片描述

第二次分解

仍然不是叶子节点,继续分解
这里写图片描述
分解后发现1、3为叶子节点,从下往上进行构造链表。
因为其父节点有左儿子,所以需要进行节点更换,将第一次分解后的树变为如下结构:
这里写图片描述
1为新的根节点。
同样方法处理右子树。
得到右子树如下:
这里写图片描述
整体结构:
这里写图片描述

将4按照同样方法来进行处理,令左儿子作为新的根节点,将原根节点接在3的后面,同时连接到5上。
这样1 -> 2 ->3 ->4 ->5 这样的链表就构造完成了。

代码

这个代码我是按照左移数值增大这么写的,但牛客网要求右移增大,所以在代码的最后我遍历翻转了下指针以达到要求:

class Solution {
public:
    TreeNode* Convert(TreeNode* pRootOfTree)
    {
        static int Counter = 0;Counter ++;//(1)
        TreeNode* pRet = pRootOfTree;
        if(pRootOfTree != NULL)
        {
            TreeNode* pLeft = Convert(pRootOfTree->left);//返回最小值节点
            TreeNode* pRight = Convert(pRootOfTree->right);//返回最小值节点
            if(pLeft != NULL)//需要更换返回的Root节点
            {
                pRet = pLeft;
                while(pLeft->left)
                {
                    pLeft = pLeft->left;
                }
                pLeft->left = pRootOfTree;
                if(pRight)
                    pRight->right = pRootOfTree;
                pRootOfTree->left = pRight;
                pRootOfTree->right = pLeft;
            }
            else if(pRight != NULL)
            {
                pRet->left = pRight;
                pRight->right = pRet;
            }
            pRet->right = NULL;
        }
        Counter--;//(2)
        if(Counter == 0)//(1),(2),包括此处为翻转左右子树指针
        {
            TreeNode* pCurr = pRet;
            while(pCurr)
            {
                TreeNode* pTemp = pCurr->left;
                pCurr->left = pCurr->right;
                pCurr->right = pTemp;
                pCurr = pCurr->right;
            }
        }
        return pRet;
    }
};
资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在当今的软件开发领域,自动化构建发布是提升开发效率和项目质量的关键环节。Jenkins Pipeline作为一种强大的自动化工具,能够有效助力Java项目的快速构建、测试及部署。本文将详细介绍如何利用Jenkins Pipeline实现Java项目的自动化构建发布。 Jenkins Pipeline简介 Jenkins Pipeline是运行在Jenkins上的一套工作流框架,它将原本分散在单个或多个节点上独立运行的任务串联起来,实现复杂流程的编排可视化。它是Jenkins 2.X的核心特性之一,推动了Jenkins从持续集成(CI)向持续交付(CD)及DevOps的转变。 创建Pipeline项目 要使用Jenkins Pipeline自动化构建发布Java项目,首先需要创建Pipeline项目。具体步骤如下: 登录Jenkins,点击“新建项”,选择“Pipeline”。 输入项目名称和描述,点击“确定”。 在Pipeline脚本中定义项目字典、发版脚本和预发布脚本。 编写Pipeline脚本 Pipeline脚本是Jenkins Pipeline的核心,用于定义自动化构建和发布的流程。以下是一个简单的Pipeline脚本示例: 在上述脚本中,定义了四个阶段:Checkout、Build、Push package和Deploy/Rollback。每个阶段都可以根据实际需求进行配置和调整。 通过Jenkins Pipeline自动化构建发布Java项目,可以显著提升开发效率和项目质量。借助Pipeline,我们能够轻松实现自动化构建、测试和部署,从而提高项目的整体质量和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值