剑指offer-第四章解决面试题思路(二叉收索树和双向链表)
题目:输入一个二叉收索树,将二叉搜索树转换成排序的双向链表。要求不能创建节点,只能将链表中的指针进行改变。
将复杂的问题简单化:
思路:二叉收索树,本身是一个排序结构,中序遍历二叉收索树就可以得到一组排序数。如下图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++代码中用的是&符来完成的。