考察点
树的遍历,双向链表
知识点
题目
分析
题目要求把一颗二叉搜索树转换成排序的双向链表,二叉搜索树和双向链表一样都有2个指针,唯一的区别就是对于树来说一个结点具有左子树右子树,对于双向链表来说是直接前驱和直接后驱。应该很自然的想到中序遍历一颗二叉搜索树就是一个有序序列,结合中序遍历的特性,当我们遍历到一个结点的时候,该结点的左子树部分一定遍历好了,但是右子树部分还没有开始,所以这个时候我们能修改的一定是这个结点的左子树指针,该指针一定指向左子树中值最大的那个结点,而这个值最大的结点的右子树指针一定指向当前这个结点
public class Node{
int val;
Node leftChild;
Node rightChild;
public Node(int data) {
this.val = data;
this.leftChild = null;
this.rightChild = null;
}
}
import java.util.Deque;
import java.util.Iterator;
public class BinaryTree {
Node root;
Node preNode;
public BinaryTree() {
this.root = null;
}
public void insertTree(int val) {
if (this.root == null) {
Node root = new Node(val);
this.root = root;
} else {
insertChildTree(this.root,val);
}
}
public void insertChildTree(Node node,int val) {
if (node != null && val < node.val) {
if (node.leftChild == null) {
node.leftChild = new Node(val);
} else {
insertChildTree(node.leftChild,val);
}
}
if (node != null && val > node.val) {
if (node.rightChild == null) {
node.rightChild = new Node(val);
} else {
insertChildTree(node.rightChild,val);
}
}
}
public Node getRoot() {
return this.root;
}
public void convert(Node root) {
if (root == null) {
return;
}
convert(root.leftChild);
root.leftChild = preNode;
if (preNode != null) {
preNode.rightChild = root;
}
preNode = root;
convert(root.rightChild);
}
public void print() {
Node firstHead = null;
while(preNode != null) {
System.out.print(preNode.val + " ");
firstHead = preNode;
preNode = preNode.leftChild;
}
System.out.println();
while(firstHead != null) {
System.out.print(firstHead.val + " ");
firstHead = firstHead.rightChild;
}
System.out.println();
}
}
public class TwentySeven {
public static void main(String[] args) {
BinaryTree binaryTree = new BinaryTree();
binaryTree.insertTree(10);
binaryTree.insertTree(6);
binaryTree.insertTree(14);
binaryTree.insertTree(4);
binaryTree.insertTree(8);
binaryTree.insertTree(12);
binaryTree.insertTree(16);
binaryTree.convert(binaryTree.getRoot());
binaryTree.print();
}
}