您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)怎樣分析python二叉樹的序列化與反序列化,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。
問題描述
序列化是將一個數(shù)據(jù)結(jié)構(gòu)或者對象轉(zhuǎn)換為連續(xù)的比特位的操作,進(jìn)而可以將轉(zhuǎn)換后的數(shù)據(jù)存儲在一個文件或者內(nèi)存中,同時也可以通過網(wǎng)絡(luò)傳輸?shù)搅硪粋€計(jì)算機(jī)環(huán)境,采取相反方式重構(gòu)得到原數(shù)據(jù)。
請?jiān)O(shè)計(jì)一個算法來實(shí)現(xiàn)二叉樹的序列化與反序列化。這里不限定你的序列 / 反序列化算法執(zhí)行邏輯,你只需要保證一個二叉樹可以被序列化為一個字符串并且將這個字符串反序列化為原始的樹結(jié)構(gòu)。
示例:
你可以將以下二叉樹:
1
/ \
2 3
/ \
4 5
序列化為 "[1,2,3,null,null,4,5]"
BFS解決
這題上面說了一大堆,其實(shí)就是把二叉樹轉(zhuǎn)化為一個字符串,并且還能把這個字符串還原成原來的二叉樹就可以了。
把二叉樹轉(zhuǎn)化為字符串可以有很多種方式,比如前序遍歷,中序遍歷,后續(xù)遍歷,BFS,DFS都是可以的,對于樹的各種遍歷具體可以看下373,數(shù)據(jù)結(jié)構(gòu)-6,樹。但這題還要求把字符串再還原成原來的二叉樹。最容易想到的就是BFS,就是一層一層從往下遍歷
來看下代碼
1public class Codec {
2
3 //把樹轉(zhuǎn)化為字符串(使用BFS遍歷)
4 public String serialize(TreeNode root) {
5 //邊界判斷,如果為空就返回一個字符串"#"
6 if (root == null)
7 return "#";
8 //創(chuàng)建一個隊(duì)列
9 Queue<TreeNode> queue = new LinkedList<>();
10 StringBuilder res = new StringBuilder();
11 //把根節(jié)點(diǎn)加入到隊(duì)列中
12 queue.add(root);
13 while (!queue.isEmpty()) {
14 //節(jié)點(diǎn)出隊(duì)
15 TreeNode node = queue.poll();
16 //如果節(jié)點(diǎn)為空,添加一個字符"#"作為空的節(jié)點(diǎn)
17 if (node == null) {
18 res.append("#,");
19 continue;
20 }
21 //如果節(jié)點(diǎn)不為空,把當(dāng)前節(jié)點(diǎn)的值加入到字符串中,
22 //注意節(jié)點(diǎn)之間都是以逗號","分隔的,在下面把字符
23 //串還原二叉樹的時候也是以逗號","把字符串進(jìn)行拆分
24 res.append(node.val + ",");
25 //左子節(jié)點(diǎn)加入到隊(duì)列中(左子節(jié)點(diǎn)有可能為空)
26 queue.add(node.left);
27 //右子節(jié)點(diǎn)加入到隊(duì)列中(右子節(jié)點(diǎn)有可能為空)
28 queue.add(node.right);
29 }
30 return res.toString();
31 }
32
33 //把字符串還原為二叉樹
34 public TreeNode deserialize(String data) {
35 //如果是"#",就表示一個空的節(jié)點(diǎn)
36 if (data == "#")
37 return null;
38 Queue<TreeNode> queue = new LinkedList<>();
39 //因?yàn)樯厦婷總€節(jié)點(diǎn)之間是以逗號","分隔的,所以這里
40 //也要以逗號","來進(jìn)行拆分
41 String[] values = data.split(",");
42 //上面使用的是BFS,所以第一個值就是根節(jié)點(diǎn)的值,這里創(chuàng)建根節(jié)點(diǎn)
43 TreeNode root = new TreeNode(Integer.parseInt(values[0]));
44 queue.add(root);
45 for (int i = 1; i < values.length; i++) {
46 //隊(duì)列中節(jié)點(diǎn)出棧
47 TreeNode parent = queue.poll();
48 //因?yàn)樵贐FS中左右子節(jié)點(diǎn)是成對出現(xiàn)的,所以這里挨著的兩個值一個是
49 //左子節(jié)點(diǎn)的值一個是右子節(jié)點(diǎn)的值,當(dāng)前值如果是"#"就表示這個子節(jié)點(diǎn)
50 //是空的,如果不是"#"就表示不是空的
51 if (!"#".equals(values[i])) {
52 TreeNode left = new TreeNode(Integer.parseInt(values[i]));
53 parent.left = left;
54 queue.add(left);
55 }
56 //上面如果不為空就是左子節(jié)點(diǎn)的值,這里是右子節(jié)點(diǎn)的值,注意這里有個i++,
57 if (!"#".equals(values[++i])) {
58 TreeNode right = new TreeNode(Integer.parseInt(values[i]));
59 parent.right = right;
60 queue.add(right);
61 }
62 }
63 return root;
64 }
65}
DFS解決
DFS遍歷是從根節(jié)點(diǎn)開始,一直往左子節(jié)點(diǎn)走,當(dāng)?shù)竭_(dá)葉子節(jié)點(diǎn)的時候會返回到父節(jié)點(diǎn),然后從從父節(jié)點(diǎn)的右子節(jié)點(diǎn)繼續(xù)遍歷……
1class Codec {
2
3 //把樹轉(zhuǎn)化為字符串(使用DFS遍歷,也是前序遍歷,順序是:根節(jié)點(diǎn)→左子樹→右子樹)
4 public String serialize(TreeNode root) {
5 //邊界判斷,如果為空就返回一個字符串"#"
6 if (root == null)
7 return "#";
8 return root.val + "," + serialize(root.left) + "," + serialize(root.right);
9 }
10
11 //把字符串還原為二叉樹
12 public TreeNode deserialize(String data) {
13 //把字符串data以逗號","拆分,拆分之后存儲到隊(duì)列中
14 Queue<String> queue = new LinkedList<>(Arrays.asList(data.split(",")));
15 return helper(queue);
16 }
17
18 private TreeNode helper(Queue<String> queue) {
19 //出隊(duì)
20 String sVal = queue.poll();
21 //如果是"#"表示空節(jié)點(diǎn)
22 if ("#".equals(sVal))
23 return null;
24 //否則創(chuàng)建當(dāng)前節(jié)點(diǎn)
25 TreeNode root = new TreeNode(Integer.valueOf(sVal));
26 //分別創(chuàng)建左子樹和右子樹
27 root.left = helper(queue);
28 root.right = helper(queue);
29 return root;
30 }
31}
把二叉樹轉(zhuǎn)化為字符串很簡單,關(guān)鍵是怎么把轉(zhuǎn)化的字符串再還原成原來的二叉樹,這里使用BFS和DFS都很容易實(shí)現(xiàn)。
關(guān)于怎樣分析python二叉樹的序列化與反序列化就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。