剑指offer——二叉搜索树与双向链表
剑指offer——二叉搜索树与双向链表
1 题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
2 利用非递归
2.1 经典编码:利用中序遍历打印二叉搜索树
package com.offer;
import java.util.Stack;
class TreeNode{
int val=0;
TreeNode left=null;
TreeNode right=null;
TreeNode(int val){
this.val=val;
}
}
public class PrintBST{
public static void printBST(TreeNode root){
if(root==null){
return;
}
Stack stack=new Stack();
TreeNode p=root;
TreeNode pre=null;
while(p!=null || !stack.isEmpty()){
while(p!=null){
stack.push(p);
p=p.left;
}
p=stack.pop();
System.out.print(p.val +" → ");
p=p.right;
}
}
public static void main(String[] args){
TreeNode root=new TreeNode(5);
TreeNode node2=new TreeNode(3);
TreeNode node3=new TreeNode(9);
TreeNode node4=new TreeNode(1);
TreeNode node5=new TreeNode(4);
TreeNode node6=new TreeNode(8);
TreeNode node7=new TreeNode(10);
root.left=node2;
root.right=node3;
node2.left=node4;
node2.right=node5;
node3.left=node6;
node3.right=node7;
printBST(root);
}
}
2.2 非递归中序遍历实现题目要求 【剑指offer——二叉搜索树与双向链表】非递归时借助栈实现递归效果,因为栈具有先进后出的特性,具有“记忆”!一般做法均是用栈实现递归!
import java.util.Stack;
class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}}
public class Solution {
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree==null){
return null;
}
if(pRootOfTree.left==null && pRootOfTree.right==null){
return pRootOfTree;
}
Stack stack = new Stack();
TreeNode p = pRootOfTree;
TreeNode pre=null;
//用于保存中序遍历时的上一个节点
boolean target=true;
//判断是否是第一次遍历,用于设置根节点,即数组第一个元素
while(p != null || !stack.isEmpty()){
while(p!=null){
stack.push(p);
p=p.left;
}//走到最左侧
p=stack.pop();
//第一次循环为最左侧元素出栈
if(target){
pRootOfTree=p;
//将中序遍历的第一个节点记为pRootOfTree,最后返回
pre=pRootOfTree;
target=false;
}else{
pre.right=p;
p.left=pre;
pre = p;
}
p=p.right;
}
return pRootOfTree;
}
}
3 利用递归 3.1 经典编码:利用中序遍历打印二叉搜索树
package com.offer;
class TreeNode{
int val=0;
TreeNode left=null;
TreeNode right=null;
TreeNode(int val){
this.val=val;
}
}
public class PrintBST{
public static void printBST(TreeNode root){
if(root==null){
return;
}
if(root!=null){//注意此处不能用while,不然会无限循环,输出最左侧节点1!
printBST(root.left);
System.out.print(root.val+" → ");
printBST(root.right);
}
}public static void main(String[] args){
TreeNode root=new TreeNode(5);
TreeNode node2=new TreeNode(3);
TreeNode node3=new TreeNode(9);
TreeNode node4=new TreeNode(1);
TreeNode node5=new TreeNode(4);
TreeNode node6=new TreeNode(8);
TreeNode node7=new TreeNode(10);
root.left=node2;
root.right=node3;
node2.left=node4;
node2.right=node5;
node3.left=node6;
node3.right=node7;
printBST(root);
}
}
3.2 递归中序遍历实现题目要求
class TreeNode{
int val=0;
TreeNode left=null;
TreeNode right=null;
TreeNode(int val){
this.val=val;
}
}
public class Solution{
public TreeNode Convert(TreeNode pRootOfTree){
if(pRootOfTree==null){
return null;
}
if(pRootOfTree.left==null && pRootOfTree.right==null){
return pRootOfTree;
}
// 1.将左子树构造成双链表,并返回链表头节点
TreeNode left=Convert(pRootOfTree.left);
TreeNode p=left;
// 2.定位至左子树双链表最后一个节点
while(p != null && p.right != null){
p=p.right;
}
// 3.如果左子树链表不为空的话,将当前root追加到左子树链表
if(left!=null){
p.right=pRootOfTree;
pRootOfTree.left=p;
}
// 4.将右子树构造成双链表,并返回链表头节点
TreeNode right=Convert(pRootOfTree.right);
// 5.如果右子树链表不为空的话,将该链表追加到root节点之后
if(right!=null){
right.left=pRootOfTree;
pRootOfTree.right=right;
}
return left!=null? left : pRootOfTree;
}
}
推荐阅读
- 急于表达——往往欲速则不达
- 慢慢的美丽
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量
- 2019-02-13——今天谈梦想()
- 考研英语阅读终极解决方案——阅读理解如何巧拿高分
- Ⅴ爱阅读,亲子互动——打卡第178天
- 低头思故乡——只是因为睡不着
- 取名——兰
- 每日一话(49)——一位清华教授在朋友圈给大学生的9条建议
- 广角叙述|广角叙述 展众生群像——试析鲁迅《示众》的展示艺术