剑指offer面试题27:二叉搜索树与双向链表
题目:输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。
由于二叉搜索树是有序的,左子结点的值小于根节点的值,右子结点的值大于根节点的值。所以在把二叉搜索树转换成排序的双向链表的时候要把左子树中的最大值的右子树指针指向根节点,把右子树中的最小值的左子树指针指向根节点。
由于先访问根节点,因此要用中序遍历的方式进行处理。
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:二叉搜索树与双向链表的更多相关文章
- 剑指Offer:面试题27——二叉搜索树与双向链表(java实现)
问题描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 思路: 将树分为三部分:左子树,根结点,右子树. 1.我们要把根结点与左 ...
- 剑指offer 面试题36.二叉搜索树与双向链表
中序递归,一个pre节点记录前一个节点 /* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; Tre ...
- 剑指Offer - 九度1503 - 二叉搜索树与双向链表
剑指Offer - 九度1503 - 二叉搜索树与双向链表2014-02-05 23:39 题目描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树 ...
- 剑指Offer:面试题24——二叉搜索树的后序遍历序列(java实现)
问题描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true,否则返回false.假设输入的数组的任意两个数字都互不相同. 思路: 1.首先后序遍历的结果是[(左子 ...
- 剑指offer(26)二叉搜索树与双向链表
题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 题目分析 要生成排序的双向列表,那么只能是中序遍历,因为中序遍历才能从小到 ...
- 【剑指Offer】26、二叉搜索树与双向链表
题目描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 解题思路: 首先要理解此题目的含义,在双向链表中,每个结 ...
- 剑指Offer - 九度1367 - 二叉搜索树的后序遍历序列
剑指Offer - 九度1367 - 二叉搜索树的后序遍历序列2013-11-23 03:16 题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出 ...
- 剑指offer(20)二叉搜索树与双向表
题目: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 思路一:递归法 1.将左子树构造成双链表,并返回链表头节点. 2.定位至左子 ...
- 剑指offer(23)二叉搜索树的后序遍历序列
题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 题目分析 1.后续遍历我们可以知道,最右边的是根节 ...
- 剑指offer(62)二叉搜索树的第K个节点
题目描述 给定一棵二叉搜索树,请找出其中的第k小的结点.例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4. 题目分析 首先,我们可以先画图.画完图后我们要想办法从 ...
随机推荐
- UIButton设置UIControlContentHorizontalAlignment调整文字对齐方式
UIButton 继承自UIControl,所以可以对UIControlContentHorizontalAlignment进行设置 btn.setImage(UIImage.init(named: ...
- crontab学习
概念 日志路径 /var/log/cron 配置路径 vi /etc/crontab 参考 https://www.cnblogs.com/kenshinobiy/p/7685229.html 问题 ...
- C#使用反射获取对象变化的情况
记录日志时, 经常需要描述对象的状态发生了怎样的变化, 以前处理的非常简单粗暴: a. 重写class的ToString()方法, 将重要的属性都输出来 b. 记录日志时: 谁谁谁 由 变更前实 ...
- jquery操作select下拉框的多种方法(选中,取值,赋值等)
Query获取Select选择的Text和Value: 语法解释: 1. $("#select_id").change(function(){//code...}); //为Sel ...
- C#读取word内容实践
C#读取word文档是如何实现的呢?我们可以使用FileStream对象来把文本文件里面的信息读取出来,但是对于word文档来说就不能使用这样的方法了. 这种情况下C#读取word文档的实现我们需要使 ...
- cobbler自动装机服务简介与配置
cobbler简介 Cobbler是一个Linux服务器安装的服务,可以通过网络启动(PXE)的方式来快速安装.重装物理服务器和虚拟机,同时还可以管理DHCP,DNS等. Cobbler可以使用命令行 ...
- Springboot+Mybatis+Thymeleaf
工具Eclipse 2018 Maven 配置 ThymeLeaf 安装: https://blog.csdn.net/xingqibaing/article/details/82787164 sp ...
- C++实现对文件中各单词词频的统计及其代码优化
先给出github上的代码链接以及项目需求 1.项目概述 这个项目的需求可以概括为:对记事本(txt)文件进行单词的词频统计和排序,排序结果以指定格式输出到默认文件中,并要求能够快速地完成整个统计和结 ...
- angularjs ng-bind-html的用法总结
angular中的$sanitize服务. 此服务依赖于ngSanitize模块.(这个模块需要加载angular-sanitize.js插件) 要学习这个服务,先要了解另一个指令: ng-bing- ...
- C语言内存四区的学习总结(二)---- 堆区
接上篇,内存四区的分析-静态区,下面来说明一下堆区总结. 堆区分析: 堆区(heap):一般由程序员分配释放(动态内存申请与释放),若程序员不释放,程序结束时可能由操作系统回 就下面的程序: #inc ...