具体的题目大意和参考思路在此处不详述(见《剑指offer》),实质就是在中序遍历的过程中调整指针的指向,关于中序遍历有递归和非递归两种操作,所以此处也用了两种方法。

方法1(递归法):

代码如下:

class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(pRootOfTree == nullptr)
return nullptr;
TreeNode * pre = nullptr;//中序遍历中当前节点的前一个节点
ConvertCore(pRootOfTree,pre);
TreeNode * rs = pRootOfTree;
while(rs->left != nullptr)//经过转换后的pRootOfTree已经指到双向链表的末端
rs = rs->left;
return rs; }
void ConvertCore(TreeNode *cur ,TreeNode * &pre)
{
if(cur == nullptr)
return;
ConvertCore(cur->left,pre);
cur->left = pre;
if(pre != nullptr)
pre->right = cur;
pre = cur;
ConvertCore(cur->right,pre); }
};

 关于递归法此处有几点需要注意:

1.实际整个过程中需要记录的节点只有一个:即在遍历过程中当前节点的前一个节点。在ConvertCore方法中,if(pre != nullptr)这一步是必须要加的,实际上是用来判断初始化时的情况。(pre初始化时为nullptr)

2.节点的left指针指向前一个节点,right指针指向后一个节点;最后返回的是rs这个指针(必须是链表的头指针)。

3.ConvertCore中的第二个参数为指针的引用,当然此处也可以是指向指针的指针即二级指针。因为函数中要操作的是指针变量本身,而不是指针变量指向的值。本题按情况类似于http://www.cnblogs.com/wangkundentisy/p/8586248.html

方法2(非递归):

代码如下:

class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(pRootOfTree == nullptr)
return nullptr;
TreeNode * pre = nullptr;//中序遍历中当前节点的前一个节点
ConvertCore(pRootOfTree,pre);
TreeNode * rs = pRootOfTree;
while(rs->left != nullptr)//经过转换后的pRootOfTree已经指到双向链表的末端
rs = rs->left;
return rs; }
void ConvertCore(TreeNode *cur ,TreeNode * &pre)
{
if(cur == nullptr)
return;
stack<TreeNode*>s;
TreeNode *p = cur;
while(p || !s.empty())
{
if(p)
{
s.push(p);
p = p->left; }
else
{
p = s.top();
s.pop();
p->left = pre;
if(pre != nullptr)
pre->right = p;
pre = p;
p = p->right;
}
} }
};

 关于非递归,感觉直接套模板,然后改改细节就能实现了,还是需要注意的一点就是if(pre != nullptr)这个判断不要忘记加。

总之,这种涉及指针的递归类问题很容易出错,一定要搞清楚整个逻辑过程,写完代码后,在心中照着代码执行一遍看看有没有出错。

《剑指offer(第二版)》——面试题36:二叉搜索树与双向链表的更多相关文章

  1. 《剑指offer》— JavaScript(26)二叉搜索树与双向链表

    二叉搜索树与双向链表 题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 思路 递归思想:把大问题转换为若干小问题: 由于Ja ...

  2. 剑指offer 面试题36.二叉搜索树与双向链表

    中序递归,一个pre节点记录前一个节点 /* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; Tre ...

  3. 《剑指offer》面试题36. 二叉搜索树与双向链表

    问题描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表.要求不能创建任何新的节点,只能调整树中节点指针的指向. 为了让您更好地理解问题,以下面的二叉搜索树为例: 我们希望将这个二叉搜 ...

  4. 《剑指offer》— JavaScript(23)二叉搜索树的后序遍历序列

    二叉搜索树的后序遍历序列 题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 相关知识 二叉查找树(B ...

  5. 《剑指offer(第二版)》面试题55——判断是否为平衡二叉树

    一.题目大意 输入一颗二叉树,判断该二叉树是否为平衡二叉树(AVL树). 二.题解 <剑指offer>上给出了两种解决方式: 1.第一种是从根节点开始,从上往下遍历每个子节点并计算以子节点 ...

  6. 《剑指offer 第二版》题解

    剑指Offer 按题号排序 面试题 3:数组中重复的数字 面试题 4:二维数组中的查找 面试题 5:替换空格 面试题 6:从头到尾打印链表 面试题 7:重建二叉树 面试题 8:二叉树的下一个节点 面试 ...

  7. 剑指offer第二版速查表

    3.数组中重复数字:每个位置放置数字与下标对应相等 O(n) 4.二维数组中的查找:右下角开始比较 O(m+n) 5.替换空格:python直接替换 6.从尾到头打印链表: 借助栈或直接利用系统调用栈 ...

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

    剑指 Offer 36. 二叉搜索树与双向链表 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表.要求不能创建任何新的节点,只能调整树中节点指针的指向. 为了让您更好地理解问题,以下面的 ...

  9. 剑指 Offer 36. 二叉搜索树与双向链表 + 中序遍历 + 二叉排序树

    剑指 Offer 36. 二叉搜索树与双向链表 Offer_36 题目描述 题解分析 本题考查的是二叉树的中序遍历以及二叉排序树的特征(二叉排序树的中序遍历序列是升序序列) 利用排序二叉树中序遍历的性 ...

随机推荐

  1. 使用libcurl作为Http client

    产品通过HTTP协议为外部提供接口服务,常规情况是客户通过HTTP协议请求服务,服务结束后通过HTTP协议将服务记录POST到请求方. 用原生C实现了一个简单的HTTP Client,只有简单的功能: ...

  2. window cmd-常用命令

    1.常用命令 dir 文件列表 cd 改变目录md 创建目录 rd 删除目录 type 显示文件内容 fc 比较目录 attrib 修改文件属性 copy 复制文件 del 删除文件 ren 文件改名 ...

  3. 基于PaaS和SaaS研发平台体系

    基于PaaS和SaaS研发的商业云平台实战 背景介绍 SaaS.PaaS.IaaS等云服务模式已经被大家普遍认可,在研发过程中借力一些PaaS和SaaS平台,能够提升产品的研发速度和功能稳定程度.本文 ...

  4. C# 后台获取前台交互判断

    前台传来明细 ,判断是否修改,在把前台 的数据组成新的类保存 public class tt { public string id { get; set; } public string e_id { ...

  5. python django day 3 页面,自动 跳转,参数传递

    zqxt_views/urls.pypath('', calc_views.index, name='home'), calc/views.pydef index(request): return r ...

  6. hdu4424 Conquer a New Region 并查集/类似最小生成树

    The wheel of the history rolling forward, our king conquered a new region in a distant continent.The ...

  7. 使用fastjson解析数据后导致顺序改变问题

    在开发过程中遇到一个问题,服务器经过排序返回后的字符串数据使用fastjson解析后,数据顺序发生变化,引起业务异常. 解决办法: 1.解析时增加参数不调整顺序 JSONObject responde ...

  8. 顺平讲try catch finally throw throws(精华)

    try catch finally  有点像if else语句 还有像javascript的服务器执行成功后的回调函数,success:function(){ 进行处理 }; throws的意思是将异 ...

  9. protobuf GetExtension

    get extention values from  proto file value, err := proto.GetExtension(imp, openrtb.E_Imp) if err != ...

  10. linux磁盘检测和修复

    显示磁盘和闪存的信息,以及分区信息 [root@bogon shell]# fdisk -l Disk /dev/sda: 21.5 GB, 21474836480 bytes, 41943040 s ...