Ricostruzione di un albero dalle informazioni di profondità

4

Ho una struttura dati che descrive un albero. I nodi sono ordinati, con informazioni "di profondità" e conoscendo l'ordine e la profondità dell'albero possono essere ricostruiti. Non sono del tutto sicuro di come descriverlo, quindi spero che questo piccolo esempio lo illustri

node #1, depth 0 // parent: none
node #2, depth 1 // parent: #1
node #3, depth 1 // parent: #1
node #4, depth 2 // parent: #3
node #5, depth 1 // parent: #1
node #6, depth 2 // parent: #5

(Ho aggiunto informazioni parent per chiarimenti. Non fa parte della struttura dati.)

Sto provando a scrivere un algoritmo (in JS, se questo è un aiuto) che andrà a scorrere su ogni nodo e costruirà un albero fuori dai dati. Sono abbastanza ricorsivo è la strada da percorrere ma oltre a questo non sono sicuro da dove cominciare. Qualche suggerimento?

Modifica: per come la vedo io ho quattro casi:

  1. Il nodo ha la profondità 0 (caso iniziale)
  2. Il nodo ha la stessa profondità del precedente
  3. Il nodo ha una profondità maggiore come precedente (dovrebbe essere solo precedente.depth + 1)
  4. Il nodo ha una profondità inferiore rispetto al precedente

Ecco il mio pseudo-codice JS finora:

process (nodes, 0);
process = function(nodes, i) {
  cur = nodes[i], prev = nodes[i-1]
  if cur.depth = 0 then cur.parent = null  // case #1
  else if cur.depth == prev.depth then cur.parent = prev.parent // case #2
  else if cur.depth > prev.depth then cur.parent = prev // case #3
  else // case #4... here's where I'm stuck.
  if i <= nodes.length then process (nodes, i+1)
}
    
posta Crummy 12.10.2013 - 08:06
fonte

2 risposte

2

È abbastanza semplice. Hai bisogno di un contenitore FIFO (stack) e di un nodo root.

Aggiungi sempre nuovi nodi come nodi del nodo frontale nello stack. Quando vedi una profondità maggiore rispetto al passato, aggiungi l'ultima nota aggiunta allo stack, prima di aggiungere il successivo. Quando vedi una profondità più piccola, pop dalla pila delta volte (di nuovo: prima di aggiungere il prossimo nodo). Non traccia la profondità attuale, è già tracciata per pila.

Pseudocodice:

root = new Node
stack = new Stack
stack.push(root)

for record in records
    delta = record.depth - (stack.size - 1)

    if delta > 0
        assert delta == 1
        stack.push(stack.front().last_child())

    while delta < 0
        stack.pop()
        delta++

    stack.front().add_child(record.node)

return root

Puoi capirlo meglio, se rappresenti la profondità come N rientri, dove N = profondità.

node #1, depth 0 // parent: none
    node #2, depth 1 // parent: #1
    node #3, depth 1 // parent: #1
        node #4, depth 2 // parent: #3
    node #5, depth 1 // parent: #1
        node #6, depth 2 // parent: #5
    
risposta data 12.10.2013 - 11:29
fonte
1

Ok, alcuni pseudocodice e brutti globali per una maggiore pigrizia:

var tree;
var position = 0;
var list = []; // to be filled with your list before you start;

process = function(depth, pos) {
  var nodes = [];
  while(list[pos + 1].depth >= depth) {
    pos = pos + 1;
    if(list[pos].depth == depth) {
      nodes.push({some_value: value, 
                  another_value: whatever,
                  children: null});
    else {
      nodes[nodes.length-1].children = process(depth + 1, pos);
    }
  };
  return nodes;
};

tree = process(0, 0);

Quindi, spero di non aver incasinato troppi dettagli, ma l'idea dovrebbe funzionare.

    
risposta data 12.10.2013 - 08:58
fonte

Leggi altre domande sui tag