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

来源:互联网 发布:网络时代知乎 编辑:程序博客网 时间:2024/06/06 04:11

题目描述

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

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

递归实现,每次用一个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);}}}


1 0
原创粉丝点击