您的位置:首页 > Web前端

剑指offer--二叉搜索树与双向链表 Java实现

2017-04-07 11:44 489 查看


题目描述

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

分析:



     对于二叉搜索树,用中序搜索算法挺适合。考虑每个子树子节点作为三部分,这里以根结点为特殊例子进行阐述



递归实现,每次用一个lastNode存放上一个子树的最后一个结点,该结点是上个已排好子树的最大的结点。

因此此时对于结点10来说,只需要建立与8之间的联系。
public class Test27_ConvertTree
{
//设为全局变量 否则无法返回最后节点
static TreeNode lastNodeInList = null;
public static void main(String[] args)
{
//创建二叉搜索树
TreeNode root = new TreeNode(6);
TreeNode node2 = new TreeNode(4);
TreeNode node3 = new TreeNode(8);
TreeNode node4 = new TreeNode(3);
TreeNode node5 = new TreeNode(5);
TreeNode node6 = new TreeNode(7);
TreeNode node7 = new TreeNode(9);
root.left = node2;
root.right = node3;
node2.left = node4;
node2.right = node5;
node3.left = node6;
node3.right = node7;

//将搜索二叉树转化为双向链表 返回链表头结点
TreeNode headNode = convertTree(root);
//打印双向链表  从左向右
System.out.println("从左向右:");
TreeNode lastNode = null;
while(headNode != null){
System.out.print(headNode.value+" ");
//正向打印时 保存最后一个节点
if(headNode.right == null){
lastNode = headNode;
}
headNode = headNode.right;
}
//打印双向链表  从右向左
System.out.println("\n从右向左:");
while(lastNode != null){
System.out.print(lastNode.value+" ");
lastNode = lastNode.left;
}

}

private static TreeNode convertTree(TreeNode root)
{
if(root == null){
return null;
}

//疑问:为什么此处的lastNodeInList要定义成全局变量,Java对象引用不是相当于指针 会对实参产生影响吗?
//将搜索二叉树转换为双向链表
convertNode(root);
//接收双向链表的尾节点 并将其转化为头结点
TreeNode headOfList = lastNodeInList;
//注意与条件 否则返回空值
while(headOfList != null && headOfList.left != null){

headOfList = headOfList.left;
}

return headOfList;
}

/**
* 整体思路:通过中序遍历获得排序节点,pNode记为当前节点,用一个lastNodeInList记录
* 最后节点(其实是先从遍历的最小节点开始记录,最后移动到最大节点)只要实现这两个节点的双向
* 链表即可,不要过度纠结细节如何遍历。
* @param pNode
*/

private static void convertNode(TreeNode pNode)
{
if(pNode == null){
return;
}
TreeNode currentNode = pNode;
//System.out.println("currentNode"+currentNode.value);
//遍历左子树
if(currentNode.left != null){
convertNode(currentNode.left);
}
//将lastNodeInList指向左子树的最左边 递归结束后指向左子树的最右边
currentNode.left = lastNodeInList;     //当右子树只有一个节点时(右节点),lastNodeInList此时指向根节点
//建立最后节点与当前节点的双向链表                                              //右节点的左边指向根节点   根节点不为空  根节点的右边指向当前节点(右节点)
if(lastNodeInList != null){            //然后将最后节点指向当前节点(右节点) 整个链表建立完毕。
lastNodeInList.right = currentNode;
}

//将最后节点指向根节点
lastNodeInList = currentNode;
System.out.println("lastNodeInList"+lastNodeInList.value);
//递归遍历右子树

if(currentNode.right != null){

convertNode(currentNode.right);

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: