题目:输入一棵二叉搜索树(即二叉排序树),将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的节点,只能调整书中节点指针的指向。
分析:
对于下图这样一棵二叉排序树来讲,转换成右边的排序的双向链表,我们考虑到二叉排序树的中序遍历是一种有序的结果,所以我们使用中序遍历,然后在遍历的过程中修改子树的节点指针指向,以达到目的。
因为当中序遍历这棵二叉树的时候,节点8的下一个节点是10,节点10的下一个节点是12,所以我们把节点10的左子树指针指向前一个节点8,其右子树指针指向后一个节点12.
针对该二叉树的代码如下:
package problem2;
/**
* @author Hutongling
*
* @time:2017年3月22日 上午11:31:07
*/
public class 二叉搜索树转换成有序双向链表 {
//static TreeNode lastNodeInList=null;
private static TreeNode convert(TreeNode root) {
TreeNode lastNodeInList=null;
TreeNode headOfList=convertNode(root,lastNodeInList);
while(headOfList!=null && headOfList.leftChild!=null)
headOfList=headOfList.leftChild;
return headOfList;
}
private static TreeNode convertNode(TreeNode node, TreeNode lastNodeInList) {
if(node==null)
return lastNodeInList;
TreeNode currentNode=node;
if(currentNode.leftChild!=null)
lastNodeInList=convertNode(currentNode.leftChild, lastNodeInList);
currentNode.leftChild=lastNodeInList;
if(lastNodeInList!=null)
lastNodeInList.rightChild=currentNode;
lastNodeInList=currentNode;
if(currentNode.rightChild!=null)
lastNodeInList=convertNode(currentNode.rightChild, lastNodeInList);
return lastNodeInList;
}
public static void main(String[] args) {
TreeNode root=new TreeNode(10);
TreeNode rLeft=new TreeNode(6);
TreeNode rRight=new TreeNode(14);
TreeNode rLLeft=new TreeNode(4);
TreeNode rLRight=new TreeNode(8);
TreeNode rRLeft=new TreeNode(12);
TreeNode rRRight=new TreeNode(16);
root.leftChild=rLeft;
root.rightChild=rRight;
rLeft.leftChild=rLLeft;
rLeft.rightChild=rLRight;
rRight.leftChild=rRLeft;
rRight.rightChild=rRRight;
TreeNode headNode=convert(root);
while(headNode.rightChild!=null){
System.out.print(headNode.value + " ");
headNode=headNode.rightChild;
}
}
}
遍历的结果为:4 6 8 10 12 14
结果符合题目的要求。