İkili Ağacı seri hale getirilmeye nasıl

oy
23

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?

Oluştur 06/01/2011 saat 04:48
kaynak kullanıcı
Diğer dillerde...                            


10 cevaplar

oy
6

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 # .....

Cevap 23/02/2013 saat 20:49
kaynak kullanıcı

oy
0

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.

Cevap 12/03/2013 saat 18:59
kaynak kullanıcı

oy
12

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ı:

  1. null adlı temsilen 0 kullanın.
  2. Ön sipariş geçişi kullanarak tamsayılar listelemek için seri hale.

Deserialization kısmı:

  1. tamsayılar listesinde alır ve seri kaldırma için özyinelemeli yardımcı yöntemini kullanır.
  2. 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;
    }
}
Cevap 24/08/2013 saat 21:28
kaynak kullanıcı

oy
0

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

Cevap 19/03/2014 saat 23:07
kaynak kullanıcı

oy
2

Ö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;
    } 
Cevap 18/01/2016 saat 17:56
kaynak kullanıcı

oy
0

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();


}

}

Cevap 21/12/2017 saat 16:43
kaynak kullanıcı

oy
-1

İş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
Cevap 28/11/2018 saat 00:14
kaynak kullanıcı

oy
0

İş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))
Cevap 28/02/2019 saat 02:19
kaynak kullanıcı

oy
-1

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));
Cevap 16/07/2019 saat 22:52
kaynak kullanıcı

oy
0

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)
Cevap 09/10/2019 saat 02:02
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more