题目:

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

二叉树的定义如下:

struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
};

思路:

在二叉树中,每个结点都有两个指向子结点的指针,在双向链表中,每个结点也有两个指针,他们分别指向前一个结点和后一个结点。两种数据结构看起来很相似,是可以通过某种方式将二叉搜索树转换为排序的双向链表。

在二叉搜索树中,当遍历到根结点时,把二叉树看成三部分,根结点、左子树和右子树,根据排序链表的定义,根结点的左指针应该指向左子树中最大的结点,即最右边的结点;根结点的右指针应该指向右子树中最小的结点,即最左边的结点。

在把左子树、右子树都转换成排序的双向排序链表(递归)之后,再跟根结点连接起来,整棵二叉搜索树就转换成了排序的双向链表。

因此在设计递归函数时,需要返回链表的头指针和尾指针,并改变当前结点的左右指针的指向。(详见代码)

代码:

#include <iostream>

using namespace std;

struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
}; TreeNode* ConvertNodes(TreeNode* pRoot,TreeNode** pTail); TreeNode* Convert(TreeNode* pRoot){
TreeNode* pTail=NULL;
return ConvertNodes(pRoot,&pTail);
} TreeNode* ConvertNodes(TreeNode* pRoot,TreeNode** pTail){
if(pRoot==NULL)
return NULL;
if(pRoot->left==NULL && pRoot->right==NULL){
*pTail=pRoot;
return pRoot;
}
TreeNode* leftHead=pRoot;
if(pRoot->left!=NULL){
leftHead=ConvertNodes(pRoot->left,pTail);
pRoot->left=*pTail;
if(*pTail!=NULL)
(*pTail)->right=pRoot;
*pTail=pRoot;
} if(pRoot->right!=NULL){
TreeNode* rightHead=ConvertNodes(pRoot->right,pTail);
pRoot->right=rightHead;
if(rightHead!=NULL)
rightHead->left=pRoot;
}
return leftHead;
}

在线测试OJ:

http://www.nowcoder.com/books/coding-interviews/947f6eb80d944a84850b0538bf0ec3a5?rp=2

AC代码:

class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
TreeNode* pTail=NULL;
return ConvertNodes(pRootOfTree,&pTail);
} TreeNode* ConvertNodes(TreeNode* pRoot,TreeNode** pTail){
if(pRoot==NULL)
return NULL;
if(pRoot->left==NULL && pRoot->right==NULL){
*pTail=pRoot;
return pRoot;
} TreeNode* leftHead=pRoot;
if(pRoot->left!=NULL){
leftHead=ConvertNodes(pRoot->left,pTail);
pRoot->left=*pTail;
if(*pTail!=NULL)
(*pTail)->right=pRoot;
*pTail=pRoot;
} if(pRoot->right!=NULL){
TreeNode* rightHead=ConvertNodes(pRoot->right,pTail);
pRoot->right=rightHead;
if(rightHead!=NULL)
rightHead->left=pRoot;
}
return leftHead;
} };

(剑指Offer)面试题27:二叉搜索树与双向链表的更多相关文章

  1. 剑指Offer:面试题27——二叉搜索树与双向链表(java实现)

    问题描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 思路: 将树分为三部分:左子树,根结点,右子树. 1.我们要把根结点与左 ...

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

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

  3. 剑指Offer - 九度1503 - 二叉搜索树与双向链表

    剑指Offer - 九度1503 - 二叉搜索树与双向链表2014-02-05 23:39 题目描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树 ...

  4. 剑指Offer:面试题24——二叉搜索树的后序遍历序列(java实现)

    问题描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true,否则返回false.假设输入的数组的任意两个数字都互不相同. 思路: 1.首先后序遍历的结果是[(左子 ...

  5. 剑指offer(26)二叉搜索树与双向链表

    题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 题目分析 要生成排序的双向列表,那么只能是中序遍历,因为中序遍历才能从小到 ...

  6. 【剑指Offer】26、二叉搜索树与双向链表

      题目描述:   输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向.   解题思路:   首先要理解此题目的含义,在双向链表中,每个结 ...

  7. 剑指Offer - 九度1367 - 二叉搜索树的后序遍历序列

    剑指Offer - 九度1367 - 二叉搜索树的后序遍历序列2013-11-23 03:16 题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出 ...

  8. 剑指offer(20)二叉搜索树与双向表

    题目: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 思路一:递归法 1.将左子树构造成双链表,并返回链表头节点. 2.定位至左子 ...

  9. 剑指offer(23)二叉搜索树的后序遍历序列

    题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 题目分析 1.后续遍历我们可以知道,最右边的是根节 ...

  10. 剑指offer(62)二叉搜索树的第K个节点

    题目描述 给定一棵二叉搜索树,请找出其中的第k小的结点.例如, (5,3,7,2,4,6,8)    中,按结点数值大小顺序第三小结点的值为4. 题目分析 首先,我们可以先画图.画完图后我们要想办法从 ...

随机推荐

  1. 深入学习Heritrix---解析CrawlController(转)

    当我们以Web UI方式使用Heritrix时,点击任务开始(start)按钮时,Heritrix就开始了它的爬取工作.但它的内部 执行流程是怎样的呢?别急,下面将慢慢道来. (一)CrawlJobH ...

  2. Twitter Storm: storm的一些常见模式

    这篇文章列举出了storm topology里面的一些常见模式: 流聚合(stream join) 批处理(Batching) BasicBolt 内存内缓存 + fields grouping 组合 ...

  3. YII Framework学习教程-YII的日志

    日志的作用(此处省略1000字) YII中的日志很好很强大,允许你把日志信息存放到数据库,发送到制定email,存放咋文件中,意见显示页面是,甚至可以用来做性能分析. YII中日志的基本配置:/yii ...

  4. HTML5中DOM元素的querySelector/querySelectorAll的工作机制

    在HTML5中,提供了强大的DOM元素选择API querySelector/querySelectorAll,允许使用JavaScript代码来完成类似CSS选择器的DOM元素选择功能.通常情况下, ...

  5. Linux基本命令(10)其他命令

    其他命令 命令 功能 命令 功能 echo 显示一字串 passwd 修改密码 clear 清除显示器 lpr 打印 lpq 查看在打印队列中等待的作业 lprm 取消打印队列中的作业 10.1 ec ...

  6. [转]linux之partprobe命令

    转自:http://www.7edown.com/edu/article/soft_48647_1.html linux上,在安装系统之后,可否创建分区并且在不重新启动机器的情况下系统能够识别这些分区 ...

  7. 对web日志文件实现按照人员、行为分类

    日志格式: method,time,name in,2015-05-06 17:37:46,Jenny1out,2015-05-06 17:37:46,Judith1in,2015-05-06 17: ...

  8. Package inputenc Error: Unicode char \u8: not set up for use with LaTeX.

    用TexStudio编辑文档时,不知是多加了空格还是啥,总是提示如下错误: Package inputenc Error: Unicode char \u8: not set up for use w ...

  9. Python单例模式研究

    方法一 import threading class Singleton(object): __instance = None __lock = threading.Lock()   # used t ...

  10. Python中的并发编程

    简介 我们将一个正在运行的程序称为进程.每个进程都有它自己的系统状态,包含内存状态.打开文件列表.追踪指令执行情况的程序指针以及一个保存局部变量的调用栈.通常情况下,一个进程依照一个单序列控制流顺序执 ...