Quale strategia devo seguire per disegnare una foresta di alberi rappresentata da una matrice

3

Ho una matrice di numeri interi che rappresentano la connettività dei nodi. Considerare i seguenti stati della matrice dopo ogni volta che viene cambiata:

0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 = > La radice di ogni nodo è essa stessa

0 | 1 | 2 | 3 | 3 | 5 | 6 | 7 | 8 | 9 = > La radice di 4 è 3

0 | 1 | 2 | 8 | 3 | 5 | 6 | 7 | 8 | 9 = > La radice di 3 è 8, quindi ora 8 è root per 3 e 4.

E così via ..

Ogni volta che due nodi vengono connessi, le modifiche dell'array. Devo disegnare un albero che rappresenta lo stato dell'array dopo ogni azione di connessione. Questo è ciò che devo disegnare:

È preso da Robert Sedgewick e dal libro Algorithms di Kevin Wayne.

Ho sbattuto la testa contro il muro ma non sono stato in grado di capire quale strategia dovrei adottare per risolvere questo problema. Dovrei registrare la profondità dell'albero e disegnare livello per livello, o dovrei scorrere l'array uno per uno e disegnare la struttura completa di ogni nodo con i suoi figli? Non ho la minima idea di come procedere comunque. Quindi sarei grato se qualcuno potesse far luce su questo.

    
posta Mikayil Abdullayev 15.12.2017 - 04:06
fonte

3 risposte

2

Penso che la tua difficoltà concettuale sia causata dall'implicazione inespressa che esiste una seconda serie di nodi 0-9. L'array non è l'insieme di nodi.

Una volta capito questo il problema diventa semplice

I nodi radice sono quelli in cui l'array all'indice dell'id nodo è uguale all'ID nodo.

I figli di qualsiasi nodo sono indicati dagli indici dell'array che contengono l'id del nodo, escludendo l'indice che equivale all'ID del nodo.

es

array = your input array
nodes = int[] {0,1,2....
roots = nodes.Where(i=> array[i] ==i)

getChildern(int node){
    return nodes.Where(i=> array[i] == node && i != node);
}
    
risposta data 19.12.2017 - 22:46
fonte
1

Un modo per avvicinarsi a questo:

  1. Cammina attraverso l'array un nodo alla volta dall'inizio
  2. Se un nodo si riferisce a se stesso, disegnalo e contrassegnalo come disegnato
  3. Se un nodo ha un genitore diverso, segui la catena fino alla radice (tenendo traccia di ogni nodo che hai colpito lungo la strada
  4. Quando arrivi alla radice o a un nodo che hai già disegnato, disegna la catena e segna ogni catena nella catena come disegnata.
risposta data 15.12.2017 - 06:35
fonte
1

Puoi provare a implementare qualcosa come DSU . Di seguito è la mia implementazione.

#include<iostream>
#include<vector>

using namespace std;

struct Node{
    int value;
    vector<Node*> childs;
};

/* I am doing a pre-order traversal Here. You can Traverse In any
 way(levelOrder will be best for verification) and verify that the tree constructed iscorrect. 
 */
void traverseOneTree(Node *tree){
    if(tree){
        cout<<tree->value<<" ";
        vector<Node*> child = tree -> childs;
        for(int i=0;i<child.size();i++)
            traverseOneTree(child[i]);
    }
}

void printAllTrees(vector<Node*> &trees){
    for(int i=0;i<trees.size();i++){
            // cout<<"i = "<<i<<trees[i]<<endl;
            traverseOneTree(trees[i]);
            cout<<endl;
    }
}

void join(vector<Node*> &trees,int child,int parent){
    if(trees[child] == NULL || trees[parent] == NULL)
            return; // invalid joining
    else{
        Node *newC = trees[child];
        trees[child] = NULL;
        trees[parent]->childs.push_back(newC);
    }
}

int main(){
    int nodes;
    cin>>nodes;
    vector<Node*> trees(nodes,NULL);
    for(int i=0;i<nodes;i++){
        trees[i] = new Node();
        trees[i]->value = i;
    }

    int joints;
    cin>>joints;
    while(joints--){
        int child,parent;
        cin>>parent>>child;
        join(trees,child,parent);
        printAllTrees(trees);
        cout<<"\n New Join\n";
    }

    return 0;

}
    
risposta data 15.12.2017 - 11:48
fonte

Leggi altre domande sui tag