二叉树的序列化和反序列化,有两种方式:
二叉树的序列化
二叉树的反序列化
二叉树转链表
本文源码
按层遍历二叉树 输出数组
public void Binary2ArrayLevel_print(BinaryTreeImpl root) {
if (check(root)) {
return;
}
Queue<BinaryTreeImpl> queue = new LinkedList<>();
queue.offer(root);
BinaryTreeImpl front = root;
BinaryTreeImpl tail = root;
while (!queue.isEmpty()) {
BinaryTreeImpl binaryTree = queue.poll();
System.out.print(binaryTree.value + " ");
if (binaryTree.left != null) {
queue.offer(binaryTree.left);
tail = binaryTree.left;
}
if (binaryTree.right != null) {
queue.offer(binaryTree.right);
tail = binaryTree.right;
}
if (binaryTree == front) {
front = tail;
System.out.println();
}
}
}
S形遍历二叉树 输出数组
public int[] Binary2ArrayS(BinaryTreeImpl root) {
if (check(root)) {
return new int[0];
}
List<Integer> list = new ArrayList<>();
Stack<BinaryTreeImpl> stack1 = new Stack();
Stack<BinaryTreeImpl> stack2 = new Stack();
stack1.push(root);
list.add(root.value);
boolean rawflag = true;
while (!stack1.empty() || !stack2.empty()) {
while (!stack1.empty()) {
BinaryTreeImpl node = stack1.pop();
if (rawflag) {
if (node.left != null) {
stack2.push(node.left);
list.add(node.left.value);
}
if (node.right != null) {
stack2.push(node.right);
list.add(node.right.value);
}
} else {
if (node.right != null) {
stack2.push(node.right);
list.add(node.right.value);
}
if (node.left != null) {
stack2.push(node.left);
list.add(node.left.value);
}
}
}
rawflag = !rawflag;
stack1 = stack2;
stack2 = new Stack<>();
}
int[] binaryTrees = list.stream().mapToInt(Integer::intValue).toArray();
return binaryTrees;
}
先序遍历二叉树 输出数组
//先序递归
public void PreOrder_recursion(BinaryTreeImpl root) {
if (root == null) {
return;
}
listPreOrder.add(root.value);
if (root.left != null) {
PreOrder_recursion(root.left);
}
if (root.right != null) {
PreOrder_recursion(root.right);
}
}
//先序非递归
public void PreOrder_stack(BinaryTreeImpl root) {
Stack<BinaryTreeImpl> stack = new Stack();
while (root != null || !stack.empty()) {
while (root != null) {
stack.push(root);
listPreOrder.add(root.value);
root = root.left;
}
root = stack.pop().right;
}
}
中序遍历二叉树 输出数组
//中序递归
private void InOrder_recursion(BinaryTreeImpl root) {
if (root == null) {
return;
}
InOrder_recursion(root.left);
listInOrder.add(root.value);
InOrder_recursion(root.right);
}
//中序非递归
private void InOrder_stack(BinaryTreeImpl root) {
Stack<BinaryTreeImpl> stack = new Stack<>();
while (root != null || !stack.empty()) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.pop();
listInOrder.add(root.value);
root = root.right;
}
}
后序遍历二叉树 输出数组
//后续遍历 递归
private void PostOrder_recursion(BinaryTreeImpl root) {
if (check(root)) {
return;
}
PostOrder_recursion(root.left);
PostOrder_recursion(root.right);
listPostOrder.add(root.value);
}
//后续遍历 双栈法
private void PostOrder_stack2(BinaryTreeImpl root) {
Stack<BinaryTreeImpl> stack1 = new Stack<>();
Stack<BinaryTreeImpl> stack2 = new Stack<>();
stack1.push(root);
while (!stack1.empty()) {
root = stack1.pop();
stack2.push(root);
if (root.left != null) {
stack1.push(root.left);
}
if (root.right != null) {
stack1.push(root.right);
}
}
while (!stack2.empty()) {
listPostOrder.add(stack2.pop().value);
}
}
//后续遍历 单栈法
public void PostOrder_stack1(BinaryTreeImpl h) {
Stack<BinaryTreeImpl> stack = new Stack<>();
stack.push(h);
BinaryTreeImpl c = null;
while (!stack.isEmpty()) {
c = stack.peek();
if (c.left != null && h != c.left && h != c.right) {
stack.push(c.left);
} else if (c.right != null && h != c.right) {
stack.push(c.right);
} else {
listPostOrder.add(stack.pop().value);
h = c;
}
}
}
先序遍历二叉树 输出数组(特殊符号)
public int[] Binary2ArrayPreOrder_Symbol(BinaryTreeImpl root) {
if (check(root)) {
return new int[]{
};
}
listPreOrder_Symbol = new ArrayList<>();
PreOrder_Symbol(root);
return listPreOrder_Symbol.stream().mapToInt(x -> x).toArray();
}
private void PreOrder_Symbol(BinaryTreeImpl root) {
if (root == null) {
listPreOrder_Symbol.add(Symbol);
return;
}
listPreOrder_Symbol.add(root.value);
PreOrder_Symbol(root.left);
PreOrder_Symbol(root.right);
}
中序遍历二叉树 输出数组(特殊符号)
public int[] Binary2ArrayInOrder_Symbol(BinaryTreeImpl root) {
if(check(root)){
return new int[]{
};
}
listInOrder_Symbol = new ArrayList<>();
InOrder_Symbol(root);
return listInOrder_Symbol.stream().mapToInt(Integer::intValue).toArray();
}
private void InOrder_Symbol(BinaryTreeImpl root){
if(root == null){
listInOrder_Symbol.add(Symbol);
return;
}
InOrder_Symbol(root.left);
listInOrder_Symbol.add(root.value);
InOrder_Symbol(root.right);
}
后序遍历二叉树 输出数组(特殊符号)
public int[] Binary2ArrayPostOrder_Symbol(BinaryTreeImpl root) {
if(check(root)){
return new int[]{
};
}
listPostOrder_Symbol = new ArrayList<>();
PostOrder_Symbol(root);
return listPostOrder_Symbol.stream().mapToInt(Integer::intValue).toArray();
}
private void PostOrder_Symbol(BinaryTreeImpl root){
if(root==null){
listPostOrder_Symbol.add(Symbol);
return;
}
PostOrder_Symbol(root.left);
PostOrder_Symbol(root.right);
listPostOrder_Symbol.add(root.value);
}
将按层次遍历的方式输入的数组 构造成一个二叉树
//1、将按层次遍历的方式输入的数组 构造成一个二叉树(写法一:非递归,堆栈)
public BinaryTreeImpl createBinaryTreeLevel(int[] array) {
if (!check(array)) {
return null;
}
BinaryTreeImpl root = null;
//借助队列实现
Queue<BinaryTreeImpl> queue = new LinkedList();
int depth = 0;
root = new BinaryTreeImpl(array[depth]);
queue.offer(root);
while (!queue.isEmpty()) {
BinaryTreeImpl binaryTree = queue.poll();
//left child exist
if (++depth < array.length && array[depth] != -1) {
binaryTree.left = new BinaryTreeImpl(array[depth]);
queue.offer(binaryTree.left);
}
//right child exist
if (++depth < array.length && array[depth] != -1) {
binaryTree.right = new BinaryTreeImpl(array[depth]);
queue.offer(binaryTree.right);
}
}
return root;
}
//1、将按层次遍历的方式输入的数组 构造成一个二叉树(写法二:递归)
private volatile int count;
public BinaryTreeImpl createBinaryTreeLevel(BinaryTreeImpl root, int[] tree_num, int i) {
if (i < tree_num.length) {
if (tree_num[i] == -1) {
return null;
} else {
//new root's lchild and rchild
BinaryTreeImpl lchild = new BinaryTreeImpl();
BinaryTreeImpl rchild = new BinaryTreeImpl();
//preOrder
root.value = tree_num[i];
root.left = createBinaryTreeLevel(lchild, tree_num, ++count);
root.right = createBinaryTreeLevel(rchild, tree_num, ++count);
}
}
return root;
}
将按先序遍历的方式输入的数组 构造成一个二叉树
public BinaryTreeImpl createPreOrder(int[] array) {
Queue<BinaryTreeImpl> queue = new LinkedList<>();
if (!check(array)) {
return null;
}
for (int value : array) {
queue.add(new BinaryTreeImpl(value));
}
BinaryTreeImpl root = PreOrder(queue);
return root;
}
private BinaryTreeImpl PreOrder(Queue<BinaryTreeImpl> queue) {
if (queue == null) {
return null;
}
BinaryTreeImpl root = queue.poll();
if (root.value == Symbol) {
return null;
}
root.left = PreOrder(queue);
root.right = PreOrder(queue);
return root;
}
将按中序遍历的方式输入的数组 构造成一个二叉树
将按后序遍历的方式输入的数组 构造成一个二叉树
public BinaryTreeImpl createPostOrder(int[] array) {
if (!check(array)) {
return null;
}
Deque<BinaryTreeImpl> queue = new LinkedList<>();
for (int value : array) {
queue.add(new BinaryTreeImpl(value));
}
BinaryTreeImpl root = PostOrder(queue);
return root;
}
private BinaryTreeImpl PostOrder(Deque<BinaryTreeImpl> queue) {
if (queue == null) {
return null;
}
BinaryTreeImpl root = queue.pollLast();
if (root.value == Symbol) {
return null;
}
root.right = PostOrder(queue);
root.left = PostOrder(queue);
return root;
}
将按照完全二叉树输入的数组 构造成一个完全二叉树
public BinaryTreeImpl createfulltree(int[] array) {
if (array == null || array.length == 0) {
return null;
}
int length = array.length;
int base = 2;
//判断一个数是否为 2的n次方-1
int indexlength = String.valueOf(Math.log(length + 1) / Math.log(base)).length();
//double型 整数 数字转字符串长度,长度为3
if (indexlength > 3) {
return null;
}
List<BinaryTreeImpl> btlist = new ArrayList<>();
for (int i = 0; i < length; i++) {
btlist.add(new BinaryTreeImpl(array[i]));
}
//注意此处的i < (length - 1) / 2,而不是i < (length + 1) / 2
for (int i = 0; i < (length - 1) / 2; i++) {
btlist.get(i).left = btlist.get(2 * i + 1);
btlist.get(i).right = btlist.get(2 * i + 2);
}
return btlist.get(0);
}
根据前序遍历序列和中序遍历序列,构建唯一一棵确定的二叉树
public BinaryTreeImpl createTreePre_InOrder(int[] PreOrderarray, int preStart, int preEnd, int[] InOrderarray, int inStart, int inEnd) {
if (preStart <= preEnd) {
//此处是PreOrderarray[preStart],不是PreOrderarray[0]
int value = PreOrderarray[preStart];
BinaryTreeImpl node = new BinaryTreeImpl(value);
int index = 0;
//循环不是从0 到 InOrderarray.length
for (int i = inStart; i <= inEnd; i++) {
if (value == InOrderarray[i]) {
index = i;
break;
}
}
//此处length = index - inStart,而不是length = index - preStart
int length = index - inStart;
node.left = createTreePre_InOrder(PreOrderarray, preStart + 1, preStart + length,
InOrderarray, inStart, index - 1);
node.right = createTreePre_InOrder(PreOrderarray, preStart + length + 1, preEnd,
InOrderarray, index + 1, inEnd);
return node;
}
return null;
}
根据后序遍历序列和中序遍历序列,构建唯一一棵确定的二叉树
public BinaryTreeImpl createTreePost_InOrder(int[] PostOrderarray, int postStart, int postEnd, int[] InOrderarray, int inStart, int inEnd) {
if (postStart <= postEnd) {
//此处是PreOrderarray[preStart],不是PreOrderarray[0]
int value = PostOrderarray[postEnd];
BinaryTreeImpl node = new BinaryTreeImpl(value);
int index = 0;
//循环不是从0 到 InOrderarray.length
for (int i = inStart; i <= inEnd; i++) {
if (value == InOrderarray[i]) {
index = i;
break;
}
}
//此处length = index - inStart,而不是length = index - preStart
int length = index - inStart;
node.left = createTreePost_InOrder(PostOrderarray, postStart, postStart + length - 1,
InOrderarray, inStart, index - 1);
node.right = createTreePost_InOrder(PostOrderarray, postStart + length, postEnd - 1,
InOrderarray, index + 1, inEnd);
return node;
}
return null;
}
右孩子转左孩子的左孩子
//将右孩子并至左孩子叶子结点,形成链表
private BinaryTreeImpl BinaryTree2LinkedList_Left(BinaryTreeImpl binaryTree) {
if (binaryTree == null) {
return null;
}
/**
* 取出节点的左右孩子,右孩子置空
* 循环左孩子(之前的)至叶子节点,
* 将右孩子(之前的)复制给该叶子节点的左孩子
*/
BinaryTree2LinkedList_Left(binaryTree.left);
BinaryTree2LinkedList_Left(binaryTree.right);
BinaryTreeImpl nodeleft = binaryTree.left;
BinaryTreeImpl noderight = binaryTree.right;
binaryTree.right = null;
BinaryTreeImpl p = binaryTree;
//注意此处的写法是p.left 而不是p,因为存在判空问题
while (p.left != null) {
p = p.left;
}
p.left = noderight;
return binaryTree;
}
左孩子转右孩子的右孩子
private BinaryTreeImpl BinaryTree2LinkedList_Right(BinaryTreeImpl binaryTree) {
if (binaryTree == null) {
return null;
}
/**
* 取出节点的左右孩子,直接把左孩子复制给跟节点的右孩子,左孩子置空
* 循环右孩子(之前的左孩子)至叶子节点,
* 将右孩子(之前的)复制给该叶子节点的右孩子
*/
BinaryTree2LinkedList_Right(binaryTree.left);
BinaryTree2LinkedList_Right(binaryTree.right);
BinaryTreeImpl nodeleft = binaryTree.left;
BinaryTreeImpl noderight = binaryTree.right;
binaryTree.left = null;
binaryTree.right = nodeleft;
BinaryTreeImpl p = binaryTree;
//注意此处的写法是p.left 而不是p,因为存在判空问题
while (p.right != null) {
p = p.right;
}
p.right = noderight;
return binaryTree;
}