数据结构与算法(JAVA版)7_4:二叉树的序列化和反序列化(以先序和层序为例)

什么是二叉树序列化呢?
把内存里的树变成序列化的结果
应用:当服务重启时,需要将内存中的数据保存成文件的形式,最好是类似数组、字符串的形式,总之,最好是线性结构放进文件里,进而可以序列化成一棵树
eg:
数据结构与算法(JAVA版)7_4:二叉树的序列化和反序列化(以先序和层序为例)_第1张图片
如果对这两颗树在先序遍历的时候,只记录数值,显然是区分不开的,因此我们可以这样做,先序遍历这两棵树所记录的数如下
tree1:[1,1,null,1,null,null,null]
tree2:[1,null,1,1,null,null,null]
这就是序列化
反序列化就是根据生成的tree1数组和tree2数组生成原始树结构(就是上图)

package com.inspire.chapter7;

import java.util.LinkedList;
import java.util.Queue;

import com.inspire.chapter7.Code03_LevelTraversalBT.Node;

public class Code05_SerializeAndReconstructTree {

	public static class Node {
		public int value;
		public Node left;
		public Node right;

		public Node(int v) {
			value = v;
		}
	}

	// 以先序的方式将一颗树序列化成一个队列
	public static Queue<Integer> preSerial(Node head) {
		if (head == null) {
			return null;
		}
		Queue<Integer> ans = new LinkedList<>();
		pres(head, ans);
		return ans;
	}

	private static void pres(Node head, Queue<Integer> ans) {
		if (head == null) {
			ans.add(null);
		} else {
			ans.add(head.value);
			pres(head.left, ans);
			pres(head.right, ans);
		}
	}

	// 将得到的队列反序列为一棵树,传入队列,返回头结点
	public static Node buildByPreQueue(Queue<Integer> prelist) {
		if (prelist == null || prelist.size() == 0) {
			return null;
		}
		return preb(prelist);
	}

	private static Node preb(Queue<Integer> prelist) {
		Integer value = prelist.poll();
		if (value == null) {
			return null;
		}
		Node head = new Node(value);
		head.left = preb(prelist);
		head.right = preb(prelist);
		return null;
	}

	// 层序的方式将树进行序列化,传入树的根结点,返回整型队列
	public static Queue<Integer> levelSerial(Node head) {
		Queue<Integer> ans = new LinkedList<>();
		if (head == null) {
			ans.add(null);
		} else {
			ans.add(head.value);
			Queue<Node> queue = new LinkedList<>();
			queue.add(head);
			while (!queue.isEmpty()) {
				Node node = queue.poll();
				if (node.left != null) {
					queue.add(node.left);
					ans.add(node.left.value);
				} else {
					ans.add(null);
				}
				if (node.right != null) {
					queue.add(node.right);
					ans.add(node.right.value);
				} else {
					ans.add(null);
				}
			}
		}
		return ans;
	}

	// 将层序序列化得到的队列反序列化为一颗树
	public static Node buildByLevelQueue(Queue<Integer> levelList) {
		if (levelList == null || levelList.size() == 0) {
			return null;
		}
		Queue<Node> queue = new LinkedList<>();
		Node head = new Node(levelList.poll());
		Node node =null;
		queue.add(head);
		while (!queue.isEmpty()) {
			node = queue.poll();
			node.left = new Node(levelList.poll());
			node.right = new Node(levelList.poll());
			if (node.left != null) {
				queue.add(node.left);
			}
			if (node.left != null) {
				queue.add(node.right);
			}
		}
		return head;
	}
	
	//层序遍历:用来打印输出反序列化的队列
	public static void level(Node head){
		if(head==null){
			return;
		}
		Queue<Node> queue=new LinkedList<>();
		queue.add(head);
		while(!queue.isEmpty()){
			Node cur=queue.poll();
			System.out.print(cur.value+" ");
			if(cur.left!=null){
				queue.add(cur.left);
			}
			if(cur.right!=null){
				queue.add(cur.right);
			}
		}
	}
	
	public static void main(String[] args) {
		// 将tree1先序输出
		Node head = new Node(1);
		head.left = new Node(1);
		head.left.right = new Node(1);
		Queue<Integer> queue = preSerial(head);
		while (!queue.isEmpty()) {
			System.out.print(queue.poll() + " ");
		}
		System.out.println();
		// 将tree2先序输出
		Node head2 = new Node(1);
		head2.right = new Node(1);
		head2.right.left = new Node(1);
		Queue<Integer> queue2 = preSerial(head2);
		while (!queue2.isEmpty()) {
			System.out.print(queue2.poll() + " ");
		}
		System.out.println();
		// 将tree1层序输出
		Queue<Integer> queue3 = levelSerial(head);
		while (!queue3.isEmpty()) {
			System.out.print(queue3.poll() + " ");
		}
	}
}

你可能感兴趣的:(算法与数据结构,队列,数据结构,算法,二叉树,java)