2011-12-29 9 views
5

Ho una struttura ad albero che ha un nodo con un ID padre (nodi figlio illimitati). Per scopi di visualizzazione ho bisogno di questa struttura ad albero come un albero binario. Come faccio questo è in ogni livello i nodi sono raggruppati in un singolo nodo in base a una condizione. Quando viene selezionato un nodo, vengono visualizzati i suoi figli. Esempio:Albero binario dall'albero generale

N-Ary tree

Il verde è quando la condizione è true e rosso è false

BTree

B, C sono stati raggruppati nel nodo di sinistra e D, E sono sulla destra in base alle loro condizioni.

DOMANDA: sto usando KnockoutJS per visualizzare il mio albero e ho bisogno di essere in grado di svolgere le normali operazioni di alberi come avere un nodo in base al suo ID, l'inserimento del nodo (s) rimozione nodo (s). Questa è la struttura che ho. C'è una struttura/modo migliore per farlo?

var tree = [ 
    { groupNodeId: "A", childNodes: [ 
     { nodeId: "A", childGroupNodes: [ 
      { groupNodeId: "B", condition: true, childNodes: [ 
       { nodeId: "B", childGroupNodes: []}, 
       { nodeId: "C", childGroupNodes: []} 
      ]}, 
      { groupNodeId: "D", condition: false, childNodes: [ 
       { nodeId: "D", childGroupNodes: []}, 
       { nodeId: "E", childGroupNodes: []} 
      ]} 
     ]} 
    ]} 
]; 
+0

Perché si utilizzano 'childGroupNodes' e' groupNodeId' per i nodi inseriti invece di continuare a utilizzare 'childNodes' e' nodeId'? Inoltre, se, ad esempio, B e C hanno ciascuno un figlio la cui condizione è vera, vuoi che quei due nodi siano raggruppati insieme? –

+1

Inoltre, suppongo 'condizione: true' in groupNode' D' è un refuso? –

+0

Sì, lo è stato, è stato corretto – Ryan

risposta

3

non sono sicuro esattamente quello che vuoi, ma partendo dal presupposto che:

  1. si desidera inserire "groupNodes", i nodi non regolari, e che groupNodes possono avere figli illimitate.
  2. L'albero originale contiene solo nodi regolari, non GroupNode.
  3. Tutti i nodi regolari hanno un nodeId, una condizione impostata su true o false e un array childNodes.
  4. Non si desidera creare GroupNode che non avrebbe figli.

quindi ecco la risposta.

function binize(tree) { 
    var left,right,t,u, 
    stack=[tree]; 
    while(t=stack.pop()) { 
    left=[]; 
    right=[]; 
    while(u=t.childNodes.pop()) { 
     (u.condition?left:right).push(u); 
     stack.push(u); 
    } 
    left.length&&t.childNodes.push({ 
     groupNodeId:left[0].nodeId, 
     condition:true, 
     childNodes:left 
    }); 
    right.length&&t.childNodes.push({ 
     groupNodeId:right[0].nodeId, 
     condition:false, 
     childNodes:right 
    }); 
    } 
} 

ho testato utilizzando questa struttura dati (si noti che l'albero è l'oggetto di livello superiore, non un array contiene).

var tree={nodeId:'A',childNodes:[ 
    {nodeId:'B',condition:true,childNodes:[]}, 
    {nodeId:'C',condition:true,childNodes:[]}, 
    {nodeId:'D',condition:false,childNodes:[ 
    {nodeId:'F',condition:false,childNodes:[]}, 
    {nodeIf:'G',condition:false,childNodes:[]} 
    ]}, 
    {nodeId:'E',condition:false,childNodes:[]} 
]}; 

Se avessi saputo qualcosa in più sul tuo albero, avrei potuto adottare un approccio diverso. Ad esempio, se l'albero non è molto profondo, potrebbe essere più efficiente (e ovviamente più pulito) scavarlo ricorsivamente.

Inoltre, non ho mai usato KnockoutJS prima e non ho idea di quali strutture piaccia. Ho appena generato le strutture che hai indicato; spero che funzionerà

+0

Hmmm, ci provo stasera, ma dalla mia comprensione ora questo forse è un set annidato? o un albero binario che ogni nodo contiene un altro albero binario – Ryan

+1

Bene, alterna le modalità, come fa il tuo esempio. Quindi il livello 1 ha il nodo di livello superiore e il livello successivo è due nodi di gruppo. Il livello successivo (figli di groupNodes) contiene tutti i figli originali del nodo superiore e il livello successivo contiene 2 groupNode per nodo principale (se il gruppo non sarebbe vuoto) e così via. Questo è quello che volevi, giusto? –

+0

Sì, lo è, in parte ...Questo mostra come creare il mio albero da un albero generale ma voglio sapere come attraversare la mia struttura in modo efficiente – Ryan