题目:输入一个二叉收索树,将二叉搜索树转换成排序的双向链表。要求不能创建节点,只能将链表中的指针进行改变。

将复杂的问题简单化:
思路:二叉收索树,本身是一个排序结构,中序遍历二叉收索树就可以得到一组排序数。如下图4.12所示。如何转换且看图4.13.将二叉搜索树变成三个部分,将左子树转换为二叉排序树,与根节点相连,右子树也转换为二叉排序树与根节点相连即可完成整个转换。

Java代码:

public class ConvertBinarySearchTree {
public class BinaryTreeNode{
int m_nValue;
BinaryTreeNode m_pLeft;
BinaryTreeNode m_pRight;
}
public BinaryTreeNode createBinaryTree(int[] pre,int start,int[] ord,int end,int length){
if(pre==null||ord==null||length<=0||pre.length!=ord.length)
return null;
int value=pre[start];
BinaryTreeNode root=new BinaryTreeNode();
root.m_nValue=value;
root.m_pLeft=root.m_pRight=null;
if(length==1){
if(pre[start]==ord[end])
return root;
else
throw new RuntimeException("inVaild put!");
}
//在中序遍历的数组中找到根节点
int i=0;
for(;i<length;i++){
if(ord[end-i]==value)
break;
}
if(i==length)
throw new RuntimeException("inVaild put");
int left=length-i-1;
int right=i;
if(left>0)
root.m_pLeft=createBinaryTree(pre,start+1,ord,end-i-1,length-i-1);
if(right>0)
root.m_pRight=createBinaryTree(pre,start+length-i,ord,end,i);
return root;
}
public void convertNode(BinaryTreeNode pNode,BinaryTreeNode lastOfList){
if (pNode == null)
return;
BinaryTreeNode pCurrent = pNode; // 递归处理左子树
if (pCurrent.m_pLeft != null)
convertNode(pNode.m_pLeft, lastOfList); // 处理当前结点
pCurrent.m_pLeft = lastOfList; // 将当前结点的左指针指向已经转换好的链表的最后一个位置
if (lastOfList != null)
lastOfList.m_pRight = pCurrent;// 将已转换好的链表的最后一个结点的右指针指向当前结点
lastOfList = pCurrent;// 更新链表的最后一个结点
// 递归处理当前结点的右子树
if (pCurrent.m_pRight != null)
convertNode(pNode.m_pRight, lastOfList); }
public BinaryTreeNode convert(BinaryTreeNode pRootOfTree){
if(pRootOfTree==null)
return null;
BinaryTreeNode pLastOfList=null;//指向双向链表的最后一个节点。
convertNode(pRootOfTree,pLastOfList);
//从尾部开始遍历找头节点
BinaryTreeNode pHeadOfList=pLastOfList;
while(pHeadOfList!=null&&pHeadOfList.m_pLeft!=null)
pHeadOfList=pHeadOfList.m_pLeft;
return pHeadOfList;
} public void print(BinaryTreeNode pHead){
if(pHead==null)
return;
if(pHead.m_pLeft!=null)
print(pHead.m_pLeft);
System.out.println(pHead.m_nValue);
if(pHead.m_pRight!=null)
print(pHead.m_pRight);
}
public static void main(String[] args){
int[] pre={10,6,4,8,14,12,16};
int[] ord={4,6,8,10,12,14,16};
ConvertBinarySearchTree cbt=new ConvertBinarySearchTree();
BinaryTreeNode pHead=cbt.createBinaryTree(pre,0,ord,6,pre.length);
cbt.print(pHead);
BinaryTreeNode pDoubleHead=cbt.convert(pHead);
System.out.println(pDoubleHead.m_nValue+"");
}
}

这段代码是有问题的,主要是convert函数中第四行中的convertNode(pRootOfTree,lastOfList)中的lastOfList的变化,不能传递到下面的执行代码中,因此在整个执行的过程中lastOfList始终等于我们给他赋的初值null。在C++代码中用的是&符来完成的。

剑指offer-第四章解决面试题思路(二叉收索树和双向链表)的更多相关文章

  1. 剑指offer第四章

    剑指offer第四章 1.二叉树的镜像 二叉树的镜像:输入一个二叉树,输出它的镜像 分析:求树的镜像过程其实就是在遍历树的同时,交换非叶结点的左右子结点. 求镜像的过程:先前序遍历这棵树的每个结点,如 ...

  2. 剑指offer编程题Java实现——面试题10二进制中1的个数

    题目: 请实现一个函数,输入一个整数,输出该整数二进制表示中1的个数.例如,把9表示成二进制是1001,有2位是1,该函数输出2解法:把整数减一和原来的数做与运算,会把该整数二进制表示中的最低位的1变 ...

  3. 【剑指Offer面试编程题】题目1503:二叉搜索树与双向链表--九度OJ

    题目描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 输入: 输入可能包含多个测试样例. 对于每个测试案例,输入的第一行为一个 ...

  4. 【剑指Offer面试编程题】题目1367:二叉搜索树的后序遍历序列--九度OJ

    题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 输入: 每个测试案例包括2行: 第一行为1个整数 ...

  5. 剑指offer-第四章解决面试题思路之总结

  6. 剑指offer-第四章解决面试题思路(字符串的排序)

    题目:输入一个字符串,打印出该字符串的全排列. 思路:将整个字符串分成两部分,第一部分为一个字符,将该字符和该字符后面的字符(直到最后一个字符)依次交换,确定第一个字符:然后固定第一个字符,将后面的字 ...

  7. 剑指offer-第四章解决面试题思路(复杂链表的复制)

    题目:请写一个函数clone(ComplexListNode pHead),实现复杂链表的复制. 复杂链表的数据结构如下:public class ComplexListNode{int m_nVal ...

  8. 剑指offer-第四章解决面试题思路(判断一个数组是否为二叉搜索树的后序遍历序列)

    二叉搜索树:二叉搜索树根节点的左边都比根节点小,右边都比根节点大. 例题:输入一个数组,判断是否为二叉搜索树的后序遍历序列,如果是,返回true,如果不是,返回flase,假设没有重复的元素. 思路: ...

  9. 剑指offer编程题Java实现——面试题3二维数组中的查找

    题目描述 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数.   下面是我实现的代码 ...

随机推荐

  1. winform webbrowser禁用网页target=blank

    /// <summary> /// 屏蔽target=_blank 的弹出窗口 /// </summary> /// <param name="sender&q ...

  2. APPIUM API整理(python)---操作类

    前言:android手机大家都很熟悉,操作有按键.触摸.点击.滑动等,各种操作方法可以通过api的方法来实现. 参考博文:http://blog.csdn.net/bear_w/article/det ...

  3. Oracle数据库的删除

    在Windows中彻底删除原先的Oracle,然后再重新安装Oracle数据库.具体步骤如下:   1. 开始->设置->控制面板->管理工具->服务,停止所有Oracle服务 ...

  4. spark学习11(Wordcount程序-本地测试)

    wordcount程序 文件wordcount.txt hello wujiadong hello spark hello hadoop hello python 程序示例 package wujia ...

  5. Pandas时间差(Timedelta)

    时间差(Timedelta)是时间上的差异,以不同的单位来表示.例如:日,小时,分钟,秒.它们可以是正值,也可以是负值.可以使用各种参数创建Timedelta对象,如下所示 - 字符串 通过传递字符串 ...

  6. cssrem 比例适配理解

    cssrem只是帮你自动计算,省去了你在切图时,从设计稿拿到的px再根据比例转换成rem的中间过程. 这个40我无法猜测, 以前设计稿给的都是按640px(iphone5s的宽)来的,我们就按照这个比 ...

  7. js 格式化时间日期函数小结2

    方法一: // 对Date的扩展,将 Date 转化为指定格式的String // 月(M).日(d).小时(h).分(m).秒(s).季度(q) 可以用 1-2 个占位符,  // 年(y)可以用  ...

  8. PHP超级全局变量、魔术变量和魔术函数的区别和联系

    PHP超级全局变量.魔术变量和魔术函数的区别和联系 一.总结 一句话总结:PHP超级全局变量主要用于web开发,魔术变量主要用于输出当前对象的信息,魔术函数则是对象的常用方法 相同点: 1.PHP超级 ...

  9. ImageView显示图像控件

    ImageView显示图像控件 一.简介 1. 2. ImageView,图像视图,直接继承自View类,它的主要功能是用于显示图片,实际上它不仅仅可以用来显示图片,任何Drawable对象都可以使用 ...

  10. JSON/JSONP浅谈

    一.什么是JSON? JSON 即 JavaScript Object Notation 的缩写,简而言之就是JS对象的表示方法,是一种轻量级的数据交换格式. JSON 是存储和交换文本信息的语法,类 ...