题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
解题思路
题目给定二叉搜索树,二叉搜索树定义:左子树的值<根节点的值<右子树的值。如果保持链表为有序状态,那么需要借助中序遍历(左跟右),正符合二叉搜索树的特性,转换为链表后,原先指向左子节点的指针调整为****指向前一个节点,原先指向右子节点的指针调整为指向后一个节点。
具体实施看代码,有详细的注释!
图示
代码实现
去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片
.
import java.util.Stack;
class TreeNode{ //定义二叉树的节点
TreeNode father;
int val;
TreeNode left;
TreeNode right;
TreeNode(TreeNode left,TreeNode right){
this.left=left;
this.right=right;
}
TreeNode(int val){
this.val=val;
}
TreeNode(){}
}
public class bsfConvertToLinkList {
//将二叉搜索树转换为双向链表
public TreeNode convert(TreeNode pRoot){//非递归
TreeNode head=null;
TreeNode pre=null;
Stack<TreeNode> stack = new Stack<>();
while (pRoot!=null||!stack.isEmpty()){
while (pRoot!=null){//遍历到最左侧的节点
stack.push(pRoot);
pRoot=pRoot.left;
}
pRoot=stack.pop();//将叶子节点弹出,
// 在下次循环中将会弹出上个叶子节点的父节点,
//进而为下面插入父节点的右子节点做准备
if (head==null){//首次建立链表
head=pRoot;
pre=pRoot;
}else{//之后每次将节点插入到链表中去
pre.right=pRoot;
pRoot.left=pre;
pre=pRoot;
}
pRoot=pRoot.right;//遍历当前节点的右子节点,如果该节点为叶子节点,则会为null,
// 下面栈将会弹出当前该节点的父节点,随后在弹出的父节点再次执行到此处时,将会遍历其右子节点
}
return head;
}
public static void main(String[] args) {
TreeNode node1=new TreeNode(10);
TreeNode node2=new TreeNode(6);
TreeNode node3=new TreeNode(14);
TreeNode node4=new TreeNode(4);
TreeNode node5=new TreeNode(8);
node1.left=node2;node1.right=node3;
node2.left=node4;node2.right=node5;
node3.left=null;node3.right=null;
node4.left=null;node4.right=null;
node5.left=null;node5.right=null;
bsfConvertToLinkList test=new bsfConvertToLinkList();
TreeNode linkNode=test.convert(node1);
System.out.println(linkNode.val+","+linkNode.right.val+","+linkNode.right.right.val);
}
}
class Solution {//另外一种写法,比较好理解
public Node treeToDoublyList(Node root) {
if (root==null){
return null;
}
ArrayList<Node> list=inorder(root);
Node head=list.get(0);
Node pre=head;
for (int i=1;i<list.size();i++){
Node node=list.get(i);
pre.right=node;
node.left=pre;
pre=pre.right;
}
pre.right=head;
head.left=pre;
return head;
}
public ArrayList<Node> inorder(Node root){
ArrayList<Node> list=new ArrayList<Node>();
Stack<Node> stack=new Stack<Node>();
Node cur=root;
while (cur!=null||!stack.isEmpty()){
while (cur!=null){
stack.push(cur);
cur=cur.left;
}
cur=stack.pop();
list.add(cur);
cur=cur.right;
}
return list;
}
}
总结
本题来源于面试经典教材《剑指offer》中 归属于二叉树类型题目。
同许多在算法道路上不断前行的人一样,不断练习,修炼自己!
如有博客中存在的疑问或者建议,可以在下方留言一起交流,感谢各位!
最后,感谢AIAS!