剑指offer每日一题算法题(java解法)
方便日后复习,从今天开始。
算法之行始于足下
[编程题]二叉搜索树与双向链表-- Java实现
------------------------------------------------------------------------------------------------------
题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向
解题思路:
二叉搜索树如上图所示,我们将其转换为配需双向链表。
根据二叉搜索树的特点:左结点的值<根结点的值<右结点的值,我们不难发现,使用二叉树的中序遍历出来的数据的数序,就是排序的顺序。因此,首先,确定了二叉搜索树的遍历方法。
接下来,我们看下图,我们可以把树分成三个部分:值为10的结点、根结点为6的左子树、根结点为14的右子树。根据排序双向链表的定义,值为10的结点将和它的左子树的最大一个结点链接起来,同时它还将和右子树最小的结点链接起来。
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
/*
1.左子树比中间节点小,右子树比中间节点大
2.排序,按从小到大,双向链表,还有个指针指向前驱
3.中序,1,2,3发现合理
*/
public class Solution {
public TreeNode Convert(TreeNode root) {
if(root==null) return null;
if(root.left==null&&root.right==null) return root;
TreeNode left=Convert(root.left);
TreeNode p=left;
while(p!=null&&p.right!=null){
p=p.right;
}if(left!=null){
p.right=root;
root.left=p;
}
TreeNode right=Convert(root.right);
if(right!=null){
root.right=right;
right.left=root;
}
return left!=null?left:root;
}
}
第二种方法
1.核心是中序遍历的非递归算法。
2.修改当前遍历节点与前一遍历节点的指针指向。
import java.util.Stack;
public TreeNode ConvertBSTToBiList(TreeNode root) {
if(root==null)
return null;
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode p = root;
TreeNode pre = null;// 用于保存中序遍历序列的上一节点
boolean isFirst = true;
while(p!=null||!stack.isEmpty()){
while(p!=null){
stack.push(p);
p = p.left;
}
p = stack.pop();
if(isFirst){
root = p;// 将中序遍历序列中的第一个节点记为root
pre = root;
isFirst = false;
}else{
pre.right = p;
p.left = pre;
pre = p;
}
p = p.right;
}
return root;