Ben bir ikili ağaç seri hale getirmek istendi nereye Bugün bir görüşmeye gitti. Birazdan çocuk için dizi tabanlı (seviye sipariş kastetmek numaralandırma) düğümün i çocukları sol çocuk için 2 * i indeksi vardı yaklaşım ve 2 * i + 1 uyguladı. Görüşmeci az ya da çok memnun görünüyordu, ama ben serialize tam ne anlama geldiğini merak ediyorum? o özellikle diske yazma veya ayrıca sadece bağlantılı liste halinde ağaç işlemi dahildir bir ağaç seri olurdu için ağaç düzleştirme ilgilendirmeyen mu derler. Ayrıca, nasıl yeniden inşa ardından (iki kat) bağlantılı listeye ağacı düzleşme ve hakkında gitmek? Bağlı listeden ağacın tam yapısını yeniden oluşturabilir misiniz?
İkili Ağacı seri hale getirilmeye nasıl
Yaklaşım 1: Ağaç verilerini searialize hem Inorder ve Preorder geçişi yapın. de-seri kullanım sipariş Ön ve inorder üzerinde BST yapmak düzgün ağaç oluşturmak üzere.
> B - -> C yapısı farklı olabilir rağmen ön sipariş olarak temsil edilebilir bir nedeni Hem gerekir.
Yaklaşım 2: Sol veya sağ alt null whereever nöbetçi gibi kullanın # .....
Nasıl bir in-sipariş geçişi gerçekleştirmek ve bir std :: liste veya ağaç düzleştirir seçtiğiniz diğer kaba kök anahtarı ve tüm düğüm anahtarlarını koyarak. Ardından hemen boost kitaplığı kullanarak seçtiğiniz std :: listesi veya konteyner seri.
Ters basit ve daha sonra, bir ikili ağaç standart ekleme kullanarak ağacı yeniden. Bu std :: listeye ağacı dönüştürmek için çok büyük bir ağacın ama çalışma zamanı için tamamen verimli olmayabilir O (n) O (log n) en fazla belirten en fazla ve ağacı yeniden inşa etmektir.
Ben Java dan C ++ benim veritabanı dönüştürme gibi ben sadece c ++ içinde kodlanmış bir ağaca seri hale getirmek için bunu yapmak üzereyim.
Bu şartların hepsini seri bölümü hakkında çoğunlukla konuşun. Seri kaldırma bölümü tek geçişte yapmak biraz zordur.
Ben de seri kaldırma için etkili bir çözüm uyguladı.
Sorun: Seri ve pozitif sayılar içeren bir ikili ağaç Deserialize.
Serileştirme kısmı:
- null adlı temsilen 0 kullanın.
- Ön sipariş geçişi kullanarak tamsayılar listelemek için seri hale.
Deserialization kısmı:
- tamsayılar listesinde alır ve seri kaldırma için özyinelemeli yardımcı yöntemini kullanır.
- Rekürsif deserializer düğüm ağaç düğümü şu ana kadar yapılmış olan bir çift (BTNode düğümünü, nextIndexToRead int) döndürür ve nextIndexToRead numaralarının tefrika listesinde okunacak sonraki sayının konumudur.
Aşağıda Java kod şudur:
public final class BinaryTreeSerializer
{
public static List<Integer> Serialize(BTNode root)
{
List<Integer> serializedNums = new ArrayList<Integer>();
SerializeRecursively(root, serializedNums);
return serializedNums;
}
private static void SerializeRecursively(BTNode node, List<Integer> nums)
{
if (node == null)
{
nums.add(0);
return;
}
nums.add(node.data);
SerializeRecursively(node.left, nums);
SerializeRecursively(node.right, nums);
}
public static BTNode Deserialize(List<Integer> serializedNums)
{
Pair pair = DeserializeRecursively(serializedNums, 0);
return pair.node;
}
private static Pair DeserializeRecursively(List<Integer> serializedNums, int start)
{
int num = serializedNums.get(start);
if (num == 0)
{
return new Pair(null, start + 1);
}
BTNode node = new BTNode(num);
Pair p1 = DeserializeRecursively(serializedNums, start + 1);
node.left = p1.node;
Pair p2 = DeserializeRecursively(serializedNums, p1.startIndex);
node.right = p2.node;
return new Pair(node, p2.startIndex);
}
private static final class Pair
{
BTNode node;
int startIndex;
private Pair(BTNode node, int index)
{
this.node = node;
this.startIndex = index;
}
}
}
public class BTNode
{
public int data;
public BTNode left;
public BTNode right;
public BTNode(int data)
{
this.data = data;
}
}
en iyi yolu (önceki açıklama belirtildiği gibi # gibi) nöbetçi gibi özel kömürü kullanmaktır. Bu akıllıca akıllıca uzay karmaşıklığı ve zaman karmaşıklığı hem de bir inorder geçişi dizisi ve bir ön sipariş / postorder geçişi dizisi inşa iyidir. o da uygulamak için daha kolay.
Bağlantılı liste ağacını yeniden inşa etmek amacıyla beri burada iyi bir uyum değil, daha iyi const eleman erişim zaman var
Ön sipariş geçişi kullanarak, İkili ağaç serileştirirler. ağaç serisini aynı ön sipariş geçişi kullanın. uç örnekleri konusunda dikkatli olun. İşte boş düğümler "#" ile temsil edilir
public static String serialize(TreeNode root){
StringBuilder sb = new StringBuilder();
serialize(root, sb);
return sb.toString();
}
private static void serialize(TreeNode node, StringBuilder sb){
if (node == null) {
sb.append("# ");
} else {
sb.append(node.val + " ");
serialize(node.left, sb);
serialize(node.right, sb);
}
}
public static TreeNode deserialize(String s){
if (s == null || s.length() == 0) return null;
StringTokenizer st = new StringTokenizer(s, " ");
return deserialize(st);
}
private static TreeNode deserialize(StringTokenizer st){
if (!st.hasMoreTokens())
return null;
String val = st.nextToken();
if (val.equals("#"))
return null;
TreeNode root = new TreeNode(Integer.parseInt(val));
root.left = deserialize(st);
root.right = deserialize(st);
return root;
}
Bunun özünü almaya çalışırken edilmiştir. Yani burada benim Java uygulamasıdır. Belirtildiği gibi, bu ikili ağaç değil BST olduğunu. seri için, bir ön sipariş geçişi (boş düğümler için "Boş" ile bir dizeye) daha kolay çalışıyor gibi görünüyor. yinelenen çağrı komple örnekle aşağıda kodunu kontrol edin. deserializing için, dizi, kaldırma (0) çalışma süresi, bir O (1) üst eleman alan bir LinkedList dönüştürülür. Ayrıca deserializing için kod yorumlarında eksiksiz bir örnek bakın. ben her yöntem için :) genel çalışma süresini mi daha kimse (serileştirip serisi kaldırılmaya) daha az mücadele yardımcı olacaktır Umut ikili ağaç kastetmek, yani n düğüm sayısı ise O (n) (giriş) için aynı çalışma zamanı ağaçta
ithalat java.util.LinkedList; ithalat java.util.List;
public class SerDesBinTree {
public static class TreeEntry<T>{
T element;
TreeEntry<T> left;
TreeEntry<T> right;
public TreeEntry(T x){
element = x;
left = null;
right = null;
}
}
TreeEntry<T> root;
int size;
StringBuilder serSB = new StringBuilder();
List<String> desList = new LinkedList<>();
public SerDesBinTree(){
root = null;
size = 0;
}
public void traverseInOrder(){
traverseInOrder(this.root);
}
public void traverseInOrder(TreeEntry<T> node){
if (node != null){
traverseInOrder(node.left);
System.out.println(node.element);
traverseInOrder(node.right);
}
}
public void serialize(){
serialize(this.root);
}
/*
* 1
* / \
* 2 3
* /
* 4
*
* ser(1)
* serSB.append(1) serSB: 1
* ser(1.left)
* ser(1.right)
* |
* |
* ser(1.left=2)
* serSB.append(2) serSB: 1, 2
* ser(2.left)
* ser(2.right)
* |
* |
* ser(2.left=null)
* serSB.append(NULL) serSB: 1, 2, NULL
* return
* |
* ser(2.right=null)
* serSB.append(NULL) serSB: 1, 2, NULL, NULL
* return
*
* |
* ser(1.right=3)
* serSB.append(3) serSB: 1, 2, NULL, NULL, 3
* ser(3.left)
* ser(3.right)
*
* |
* ser(3.left=4)
* serSB.append(4) serSB: 1, 2, NULL, NULL, 3, 4
* ser(4.left)
* ser(4.right)
*
* |
* ser(4.left=null)
* serSB.append(NULL) serSB: 1, 2, NULL, NULL, 3, 4, NULL
* return
*
* ser(4.right=null)
* serSB.append(NULL) serSB: 1, 2, NULL, NULL, 3, 4, NULL, NULL
* return
*
* ser(3.right=null)
* serSB.append(NULL) serSB: 1, 2, NULL, NULL, 3, 4, NULL, NULL, NULL
* return
*
*/
public void serialize(TreeEntry<T> node){
// preorder traversal to build the string
// in addition: NULL will be added (to make deserialize easy)
// using StringBuilder to append O(1) as opposed to
// String which is immutable O(n)
if (node == null){
serSB.append("NULL,");
return;
}
serSB.append(node.element + ",");
serialize(node.left);
serialize(node.right);
}
public TreeEntry<T> deserialize(TreeEntry<T> newRoot){
// convert the StringBuilder into a list
// so we can do list.remove() for the first element in O(1) time
String[] desArr = serSB.toString().split(",");
for (String s : desArr){
desList.add(s);
}
return deserialize(newRoot, desList);
}
/*
* 1
* / \
* 2 3
* /
* 4
*
* deser(root, list) list: 1, 2, NULL, NULL, 3, 4, NULL, NULL, NULL
* root = new TreeEntry(1) list: 2, NULL, NULL, 3, 4, NULL, NULL, NULL
* root.left = deser(root.left, list) // **
* root.right = deser(root.right, list) // *-*
* return root // ^*^
*
*
* so far subtree
* 1
* / \
* null null
*
* deser(root.left, list)
* root.left = new TreeEntry(2) list: NULL, NULL, 3, 4, NULL, NULL, NULL
* root.left.left = deser(root.left.left, list) // ***
* root.left.right = deser(root.left.right, list) // ****
* return root.left // eventually return new TreeEntry(2) to ** above after the two calls are done
*
* so far subtree
* 2
* / \
* null null
*
* deser(root.left.left, list)
* // won't go further down as the next in list is NULL
* return null // to *** list: NULL, 3, 4, NULL, NULL, NULL
*
* so far subtree (same, just replacing null)
* 2
* / \
* null null
*
* deser(root.left.right, list)
* // won't go further down as the next in list is NULL
* return null // to **** list: 3, 4, NULL, NULL, NULL
*
* so far subtree (same, just replacing null)
* 2
* / \
* null null
*
*
* so far subtree // as node 2 completely returns to ** above
* 1
* / \
* 2 null
* / \
* null null
*
*
* deser(root.right, list)
* root.right = new TreeEntry(3) list: 4, NULL, NULL, NULL
* root.right.left = deser(root.right.left, list) // *&*
* root.right.right = deser(root.right.right, list) // *---*
* return root.right // eventually return to *-* above after the previous two calls are done
*
* so far subtree
* 3
* / \
* null null
*
*
* deser(root.right.left, list)
* root.right.left = new TreeEntry(4) list: NULL, NULL, NULL
* root.right.left.left = deser(root.right.left.left, list) // *(*
* root.right.left.right = deser(root.right.left.right, list) // *)*
* return root.right.left // to *&*
*
* so far subtree
* 4
* / \
* null null
*
* deser(root.right.left.left, list)
* // won't go further down as the next in list is NULL
* return null // to *(* list: NULL, NULL
*
* so far subtree (same, just replacing null)
* 4
* / \
* null null
*
* deser(root.right.left.right, list)
* // won't go further down as the next in list is NULL
* return null // to *)* list: NULL
*
*
* so far subtree (same, just replacing null)
* 4
* / \
* null null
*
*
* so far subtree
* 3
* / \
* 4 null
* / \
* null null
*
*
* deser(root.right.right, list)
* // won't go further down as the next in list is NULL
* return null // to *---* list: empty
*
* so far subtree (same, just replacing null of the 3 right)
* 3
* / \
* 4 null
* / \
* null null
*
*
* now returning the subtree rooted at 3 to root.right in *-*
*
* 1
* / \
* / \
* / \
* 2 3
* / \ / \
* null null / null
* /
* 4
* / \
* null null
*
*
* finally, return root (the tree rooted at 1) // see ^*^ above
*
*/
public TreeEntry<T> deserialize(TreeEntry<T> node, List<String> desList){
if (desList.size() == 0){
return null;
}
String s = desList.remove(0); // efficient operation O(1)
if (s.equals("NULL")){
return null;
}
Integer sInt = Integer.parseInt(s);
node = new TreeEntry<T>((T)sInt);
node.left = deserialize(node.left, desList);
node.right = deserialize(node.right, desList);
return node;
}
public static void main(String[] args) {
/*
* 1
* / \
* 2 3
* /
* 4
*
*/
SerDesBinTree<Integer> tree = new SerDesBinTree<>();
tree.root = new TreeEntry<Integer>(1);
tree.root.left = new TreeEntry<Integer>(2);
tree.root.right = new TreeEntry<Integer>(3);
tree.root.right.left = new TreeEntry<Integer>(4);
//tree.traverseInOrder();
tree.serialize();
//System.out.println(tree.serSB);
tree.root = null;
//tree.traverseInOrder();
tree.root = tree.deserialize(tree.root);
//tree.traverseInOrder();
// deserialize into a new tree
SerDesBinTree<Integer> newTree = new SerDesBinTree<>();
newTree.root = tree.deserialize(newTree.root);
newTree.traverseInOrder();
}
}
İşte (değiştirilmiş) seviye malzeme geçişi kullanarak İkili ağaç seri başka bir yoludur. Tüm dengesiz, dengeli, doğru çarpık, sola çarpık ağaç Kapaklar [Sadece çalıştığını, kopyalayıp yapıştırarak].
class TreeNode():
def __init__(self, val):
self.val = val
self.left = None
self.right = None
def getHeight(root):
if root == None:
return 0
return max(getHeight(root.left), getHeight(root.right)) + 1
treeArray = []
def levelOrderTraversal(root, level, numOfNodes):
if level <= 0 and numOfNodes <=0:
return
numOfNodes -= 1
if root != None and level == 1:
treeArray.append(root.val)
elif root == None and level == 1:
treeArray.append("$")
if root != None:
levelOrderTraversal(root.left, level-1, numOfNodes)
levelOrderTraversal(root.right, level-1, numOfNodes)
else:
levelOrderTraversal(root, level-1, numOfNodes)
levelOrderTraversal(root, level-1, numOfNodes)
def treeToIntArray(root):
h = getHeight(root)
for i in range(1, h+1):
levelOrderTraversal(root,i, i*2)
return treeArray
def intArrayToTree():
n = len(treeArray)
treeArrayOfObjects = [0]*len(treeArray)
for i in range(n):
if treeArray[i] != "$":
root = TreeNode(treeArray[i])
treeArrayOfObjects[i] = root
#Linking the child nodes
for i in range(n):
if treeArray[i] != "$":
root = treeArrayOfObjects[i]
if 2 * i + 1 < n:
root.left = treeArrayOfObjects[2*i + 1]
if 2 * i + 2 < n:
root.right = treeArrayOfObjects[2*i + 2]
treeArray[i] = root
return treeArrayOfObjects[0]
"""
root = TreeNode(7)
root.left = TreeNode(3)
root.right = TreeNode(9)
root.left.left = TreeNode(1)
root.left.right = None
root.right.left = None
root.right.right = TreeNode(4)
"""
root = TreeNode(7)
root.right = TreeNode(9)
root.right.right = TreeNode(4)
root.right.right.right = TreeNode(5)
print treeToIntArray(root)
root = intArrayToTree()
print root.val
print root.right.val
print root.right.right.val
print root.right.right.right.val
İşte Python geç bir cevaptır. O (derinlik önce) ön sipariş seri kullanır ve bir listesini döndürür strings. Deserialization ağacını döndürür.
class Node:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
# This method serializes the tree into a string
def serialize(root):
vals = []
def encode(node):
vals.append(str(node.val))
if node.left is not None:
encode(node.left)
else:
vals.append("L")
if node.right is not None:
encode(node.right)
else:
vals.append("R")
encode(root)
print(vals)
return vals
# This method deserializes the string back into the tree
def deserialize(string_list):
def create_a_tree(sub_list):
if sub_list[0] == 'L' or sub_list[0] == 'R':
del sub_list[0]
return
parent = Node(sub_list[0])
del sub_list[0]
parent.left = create_a_tree(sub_list)
parent.right = create_a_tree(sub_list)
return parent
if len(string_list) != 0:
root_node = create_a_tree(string_list)
else:
print("ERROR - empty string!")
return 0
return root_node
Test için:
tree1 = Node('root', Node('left'), Node('right'))
t = deserialize(serialize(tree1))
print(str(t.right.val))
Seri bir dosya ya da geçici bellek içinde depolanmış ya da aynı ya da başka bir bilgisayar ortamında, daha sonra yeniden inşa edilmesi için bir ağ bağlantısı, link üzerinde iletilecek şekilde bir bit dizisinin bir veri yapısı veya nesne dönüştürme işlemidir.
Deserialization orijinal ağaç yapısına geri dize dönüştürme işlemidir.
serileştirme ve seriyi kaldırma Konsept bir derleyici kodlamak için ne kadar çok benziyor. Orada tüm derleme sürecinde birden fazlar ama biz soyut tutmaya çalışacağız.
kod parçası göz önüne alındığında, derleyici belirteçleri, farklı iyi tanımlanmış bileşenleri keser (örneğin, int belirteç, çift bir belirteç, {bir belirteç} başka belirteç, vs). [Derleme soyut düzeyde bir gösteri bağlantısı] [1].
Serile: Bir String ağacı seri hale ön sipariş geçişi mantığı kullanabilirsiniz. Bir ağaçta bir boş gösterici / düğümü belirtmek için "X" ekleyecektir. Buna ek olarak, akılda bizim seri kaldırma mantığı tutmak, biz "" seri kaldırma işlemi ile her bir düğüm değeri bölünmüş erişebilmeleri için her tefrika düğüm değeri sonra "" eklemeniz gerekir.
Leetcode linki: https://leetcode.com/problems/serialize-and-deserialize-binary-tree/
Geri tarafından açıklanması SWE Youtube kanalı Arkaya : https://www.youtube.com/watch?v=suj1ro8TIVY
For example:
You may serialize the following tree:
1
/ \
2 3
/ \
4 5
as "[1,2,null,null,3,4,null,null,5,null,null,]"
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Codec {
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
if(root == null)
return "X,";
String leftSerialized = serialize(root.left);
String rightSerialized = serialize(root.right);
return root.val + "," + leftSerialized + rightSerialized;
}
private TreeNode deserializeHelper(Queue<String> queue)
{
String nodeValue = queue.poll();
if(nodeValue.equals("X"))
return null;
TreeNode newNode = new TreeNode(Integer.valueOf(nodeValue));
newNode.left = deserializeHelper(queue);
newNode.right = deserializeHelper(queue);
return newNode;
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
Queue<String> queue = new LinkedList<>();
queue.addAll(Arrays.asList(data.split(",")));
return deserializeHelper(queue);
}
}
//Codec object will be instantiated and called as such:
//Codec codec = new Codec();
//codec.deserialize(codec.serialize(root));
Ben ön sipariş kullanmıyorum ama BFS'ye kullanıyorum. Bu bir sorudur leetcode
ön sipariş kullanırken uygulanması insanlar büyük çoğunluğu yanlıştır: beklenen sonucu olmalıdır
onlar çünkü "[1,2,3, null, null, 4,5]", ancak bunun yerine çoğunluk insanlar "[null, 4,5, null, null, boş 1,2,3]" olarak çıktı yazdırmak seviyelerinin hariç.
Burada doğru sonuçla benim uygulamasıdır.
class Node(object):
def __init__(self,data):
self.left = None
self.right = None
self.data = data
def serialize(root):
queue = [(root,0)]
result = []
max_level_with_value = 0
while queue:
(node,l) = queue.pop(0)
if node:
result.append((node.data,l))
queue.extend([(node.left,l+1),
(node.right,l+1)
])
max_level_with_value = max(max_level_with_value,l)
else:
result.append(('null',l))
filter_redundant(result,max_level_with_value)
def filter_redundant(result,max_level_with_value):
for v,l in result:
if l<= max_level_with_value:
print(v)
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.right.left = Node(4)
root.right.right = Node(5)
serialize(root)













