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

由于二叉搜索树是有序的,左子结点的值小于根节点的值,右子结点的值大于根节点的值。所以在把二叉搜索树转换成排序的双向链表的时候要把左子树中的最大值的右子树指针指向根节点,把右子树中的最小值的左子树指针指向根节点。

由于先访问根节点,因此要用中序遍历的方式进行处理。

package Solution;

public class No27ConvertBinarySearchTreeToLinkedList {

    static class BinaryTreeNode {
int value;
BinaryTreeNode left;
BinaryTreeNode right; public BinaryTreeNode() { } public BinaryTreeNode(int value, BinaryTreeNode left,
BinaryTreeNode right) {
this.value = value;
this.left = left;
this.right = right;
}
} public static BinaryTreeNode convert(BinaryTreeNode root) {
BinaryTreeNode lastNodeInList = null;
lastNodeInList = convertToNode(root, lastNodeInList);
BinaryTreeNode head = lastNodeInList;
// 从尾节点返回头结点
while (head != null && head.left != null) {
head = head.left;
}
printList(head);
return head;
} private static BinaryTreeNode convertToNode(BinaryTreeNode node,
BinaryTreeNode lastNodeInList) {
if (node == null)
return null;
BinaryTreeNode current = node;
// 递归的处理左子树
if (current.left != null)
lastNodeInList = convertToNode(current.left, lastNodeInList);
// 使链表中的最后一个结点指向左子树的最小的节点
current.left = lastNodeInList;
// 链表中的最后一个结点指向当前节点,当前节点就成了链表中的最后一个结点
if (lastNodeInList != null)
lastNodeInList.right = current;
lastNodeInList = current;
// 递归转换右子树
if (current.right != null)
lastNodeInList = convertToNode(current.right, lastNodeInList); return lastNodeInList;
} public static void printList(BinaryTreeNode head) {
while (head != null) {
System.out.print(head.value + ",");
head = head.right;
}
} // 中序遍历二叉树
public static void printTree(BinaryTreeNode root) {
if (root != null) {
printTree(root.left);
System.out.print(root.value + ",");
printTree(root.right);
}
} public static void main(String[] args) {
BinaryTreeNode node1 = new BinaryTreeNode();
BinaryTreeNode node2 = new BinaryTreeNode();
BinaryTreeNode node3 = new BinaryTreeNode();
BinaryTreeNode node4 = new BinaryTreeNode();
BinaryTreeNode node5 = new BinaryTreeNode();
BinaryTreeNode node6 = new BinaryTreeNode();
BinaryTreeNode node7 = new BinaryTreeNode();
node7.value = 16;
node6.value = 12;
node5.value = 14;
node5.left = node6;
node5.right = node7;
node3.value = 4;
node4.value = 8;
node2.value = 6;
node2.left = node3;
node2.right = node4;
node1.value = 10;
node1.left = node2;
node1.right = node5;
printTree(node1);
System.out.println();
System.out.println("=============打印链表================");
convert(node1);
}
}

剑指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. 12.Redis运维点

    12.Redis运维点12.1 Linux配置优化12.1.1 内存分配控制12.1.2 swappiness12.1.3 THP12.1.4 OOM killer12.1.5 使用NTP12.1.6 ...

  2. DOCKER学习 docker

    DOCKER只能安装到LIUX系列机器上 如果WINDOWS想安装必须通过虚拟机来完成. 比如用VM,VBOX等 安装之前需要用ROOT账户 su 安装DOCKER (CE是个人版本,EE是企业版本) ...

  3. NC 创建表空间数据库

    1.首先创建表空间 CREATE SMALLFILE TABLESPACE "NNC_DATA01" LOGGING DATAFILE 'D:\NCOracle\nc633sd\N ...

  4. docker常用操作备忘

    一.docker安装 参考资料:阿里云镜像加速1. 安装/升级Docker客户端 curl -fsSL https://get.docker.com | bash -s docker --mirror ...

  5. Oracle学习——dmp文件(表)导入与导出

    Oracle学习——dmp文件(表)导入与导出 2014-12-28      0个评论    来源:张文康 廊坊师范学院信息技术提高班 第九期   收藏    我要投稿 前言 关于dmp文件我们用的 ...

  6. union: redis config

    # how to save to disk # warning: how to disable, just comment this config save $second $changes

  7. S系统的不好的实践

    多个项目 多个分支放在一个SVN里边维护,导致多股力量并行开发时候的代码覆盖的风险可能性很大,,  好的实践是维护独立的SVN,彼此分离开来

  8. JQUERY-自定义插件-ajax-跨域访问

    正课: 1. ***自定义插件: 2. Ajax 3. *****跨域访问: 1. ***自定义插件: 前提: 已经用html,css,js实现了 2种风格: 1. jQueryUI侵入式: 1. c ...

  9. 浅谈nodejs和php

    现在,Web开发公司和开发人员可以选择多种技术栈来构建Web应用程序.早期网络发展,不同的技术被用于前端和后端开发.但是,随着Node.js的发布,布局发生了变化,因为它允许开发人员使用 JavaSc ...

  10. c# 将object尝试转为指定对象

    主方法: /// <summary> /// 将object尝试转为指定对象 /// </summary> /// <param name="data" ...