Hogyan sorosításához bináris fa

szavazat
23

Elmentem egy interjút, ahol ma megkértek, hogy sorosításához bináris fa. I végre egy tömb-alapú megközelítés, ahol a gyerekek i csomópont (számozás szint-sorrendben bejárás) voltak a 2 * i index a bal gyermek, és 2 * i + 1 a jobb fia. A kérdező tűnt többé-kevésbé elégedett, de kíváncsi vagyok, hogy mit jelent pontosan serialize? Vajon kifejezetten vonatkoznak összeolvasztás a fa lemezre írásnál, vagy pedig szerializálásáról egy fa is tartalmazhat csak fordult a fa egy láncolt lista, mondjuk. Továbbá, hogyan érjük el egyengető a fa egy (kétszeresen) láncolt lista, majd rekonstruálva? Tud újra a pontos szerkezete a fa a láncolt lista?

A kérdést 06/01/2011 04:48
a forrás felhasználó
Más nyelveken...                            


10 válasz

szavazat
6

1. megközelítés: Nem mind Inorder és Előrendelési bejárás a searialize a fa adatokat. A de-sorszámozás használatra előrendelés do BST Inorder megfelelő módon kialakítani a fát.

Be kell egyrészt azért, mert -> A B -> C jelölhető előrendelhető bár a szerkezet különböző lehet.

2. megközelítés: A #, mint egy őrszem Bárhol a bal vagy a jobb gyermek null .....

Válaszolt 23/02/2013 20:49
a forrás felhasználó

szavazat
0

Mit szólnál működés közbeni érdekében bejárás és véget a gyökér kulcs, és minden csomópont kulcsokat egy std :: listából vagy más tartály választott, amely kisimítja a fát. Ezután egyszerűen szerializálni az std :: listából vagy konténer választott a boost könyvtárban.

A fordított egyszerű, majd újjáépíteni a fa standard beillesztési egy bináris fa. Ez nem lehet teljesen hatékony egy nagyon nagy fa, de futás közben átalakítani a fa egy std :: lista O (n) legfeljebb, és újjáépíteni a fa O (log n) a legtöbb.

Én körülbelül ezt sorosításához egy fa csak kódolt fel c ++, mint én konvertálása adatbázis Java C ++.

Válaszolt 12/03/2013 18:59
a forrás felhasználó

szavazat
12

Mindazok cikkek beszélni többnyire a sorszámozás részét. A deserialization része kissé trükkös csinálni egy menetben.

Azt már végre egy hatékony megoldás deserialization is.

Probléma: sorosításához és deserialize egy bináris fa, amely a pozitív számok.

Sorszámozás rész:

  1. 0 használatával képviseli null.
  2. Sorosításához felsorolni az egész számok segítségével előrendelésre bejárás.

Deserialization rész:

  1. Tudomásul listán egészek, és használja rekurzív segítő módszert deserialization.
  2. Rekurzív deserializer vissza egy pár (BTNode csomópont, int nextIndexToRead) adott csomópont csomópontja épített eddig, és nextIndexToRead jelentése helyzete a következő számot kell olvasni a szerializált számok listája.

Az alábbiakban a kód Java:

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;
    }
}
Válaszolt 24/08/2013 21:28
a forrás felhasználó

szavazat
0

A legjobb módja az, hogy egy speciális karakter (mint #, mint a korábbi megjegyzést említik), mint őrszem. Ez jobb, mint szerkesztünk egy inorder bejárása tömb és egy előrendelésre / postorder bejárás tömb, mind térben bonyolultsága bölcs és időbonyolultsága bölcs. ez is módja könnyebben megvalósítható.

A csatolt felsorolás nem jó illeszkedést óta itt annak érdekében, hogy rekonstruálják a fa, jobb, ha van const elem elérési idő

Válaszolt 19/03/2014 23:07
a forrás felhasználó

szavazat
2

Az előre érdekében bejárás szerializálni bináris fa. Használja ugyanazt a pre érdekében bejárás a deserialize fa. Légy óvatos a szélső esetek. Itt null csomópontok által képviselt „#”

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;
    } 
Válaszolt 18/01/2016 17:56
a forrás felhasználó

szavazat
0

Már próbál a lényeget. Tehát itt van a Java megvalósítása. Mint említettük, ez egy bináris fa nem BST. Mert szerializálásáról, előrendelésre vásárolható bejárás tűnik, hogy működik egyszerűbb (egy string „NULL” for null csomópontok). Kérjük, ellenőrizze az alábbi kódot egy teljes példa rekurzív hívások. A deserializing, a húr alakítjuk át láncolt lista, ahol eltávolítás (0) kap a felső eleme egy O (1) futási ideje. Kérjük, olvassa el a teljes például a megjegyzéseket a kódot deserializing. Remélem, hogy segít valaki küzd kisebb, mint én :) A teljes működési ideje minden módszer (sorosításához és deserialize) ugyanaz működési ideje bináris fa bejárás, tehát O (n), ahol n a csomópontok száma (bejegyzés) a fában

import java.util.LinkedList; import 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();


}

}

Válaszolt 21/12/2017 16:43
a forrás felhasználó

szavazat
-1

Itt van egy másik módja szerializálásáról bináris fa segítségével (módosított) komissiózó bejárás. [Csak másold be, akkor működik] Tartalmazza az összes kiegyensúlyozatlan, kiegyensúlyozott, jobbra ferde, balra ferde fa.

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
Válaszolt 28/11/2018 00:14
a forrás felhasználó

szavazat
0

Itt van egy késői válasz Python. Ez használ (mélységi) előrendelésre sorozatprogramozásának listáját adja vissza strings. Deserialization visszaadja a fa.

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

Tesztelni:

tree1 = Node('root', Node('left'), Node('right'))
t = deserialize(serialize(tree1))
print(str(t.right.val))
Válaszolt 28/02/2019 02:19
a forrás felhasználó

szavazat
-1

Sorszámozás a folyamat, amely egy adatszerkezetet vagy tárgy egy bitsorozatot úgy, hogy lehet tárolni egy fájl vagy memória puffer, vagy továbbított hálózati kapcsolaton keresztül a linket rekonstruálható később ugyanazon vagy egy másik számítógépes környezetben.

Deserialization az a folyamat átalakítása a húr vissza az eredeti fa szerkezet.

Fogalma sorozatprogramozásának deserialization nagyon hasonlít ahhoz, amit a fordítóprogramnak kódolni. Vannak több fázisban az egész fordítási folyamatot, de megpróbáljuk tartani elvont.

Adott egy darab kód, fordító megtöri különböző jól definiált komponensek jelzőt (például int egy jelképes, kettős egy másik token, {egy token,} egy másik token, stb). [Link bemutatót az absztrakt szintű összeállítás] [1].

Sorszámozás: használjuk előrendelésre bejárás logikája szerializálásáról fa egy string. Mi lesz hozzá "X" jelöli a null pointer / node egy fa. Ezen kívül, hogy megtartsuk a deserialization logikát követve, mi kell hozzá „” miután minden sorozatban csomópont értékét úgy, hogy a folyamat deserialization elérheti minden csomópont értéke split „”.

Leetcode Link: https://leetcode.com/problems/serialize-and-deserialize-binary-tree/

Magyarázat a háttal SWE Youtube csatorna : 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));
Válaszolt 16/07/2019 22:52
a forrás felhasználó

szavazat
0

Én nem használ előrendelhető, de én vagyok a BFS. Ez egy kérdés leetcode

Az emberek többsége végrehajtás helytelen használata előrendelhető: a várt eredményt kell

"[1,2,3, null, null, 4,5]", hanem többségi emberek kinyomtatni a kimenetet "[1,2,3, null, null, 4,5, null, null]", mivel ők nem számítva a szinteket.

Itt van a végrehajtás a helyes eredményt.

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)
Válaszolt 09/10/2019 02:02
a forrás felhasználó

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