Domanda

Ho una lezione con la seguente definizione,

class BinomialNode
    {
        public int key; // The key value
        public int x_point; // x co-ordinate for drawing
        public int y_point; // y co-ordinate for drawing
        public int degree;  // number of siblings/children for current node
        public BinomialNode parent;
        public BinomialNode child;
        public BinomialNode sibling;
        ...
    }

Stiamo imparando cumuli binomiali al college e ho implementato gli algoritmi di unione e inserire in codice. Almeno, quando metto in pausa Visual Studio e vado oltre la "gente del posto" (litigando il mouse su una variabile), vedo i dati come mi aspetto.

Come esperimento, ho aggiunto 2 variabili extra al "nodo binomiale" standard. Sono x_point e y_point. Ora durante l'esecuzione del programma vedo questo,enter image description here

Si prega di notare l'area che ho indicato sopra. Dovrebbe rappresentare lo stesso nodo, ma come possiamo vedere, il valore di x_point è diverso. (In altri casi, Y_point è diverso)

Qualcuno ha idea del perché sta accadendo? Come capisco le cose, se rappresenta lo stesso nodo, i dati dovrebbe Sii identico. Ma non lo è - il che significa che non è lo stesso nodo. Come può essere possibile? Se ignoro le mie variabili "extra" x_point e y_point, il codice funziona perfettamente! In effetti, non avrei nemmeno saputo che questo fosse un problema.

Non è visibile dal mio frammento, ma x_point e y_point sono gli unici valori che modifichi al di fuori della definizione della classe. Gli altri, mentre il pubblico vengono letti solo da.

EDIT: ecco il codice che ho realizzato,

class BinomialNode
{
    public int key; // The key value
    public int x_point; // x co-ordinate for drawing
    public int y_point; // y co-ordinate for drawing
    public int degree;  // number of siblings/children for current node
    public BinomialNode parent;
    public BinomialNode child;
    public BinomialNode sibling;

    // Binomial Link takes the tree rooted at y and makes it a child of z
    private static void Binomial_Link(ref BinomialNode y,ref  BinomialNode z)
    {
        y.parent = z;
        y.sibling = z.child;
        z.child = y;
        z.degree++;
    }

    // This merges the root lists of H1 and H2 into a single linked list that is sorted
    // by degree in increasing order
    private static BinomialNode Binomial_Heap_Merge(BinomialNode H1, BinomialNode H2)
    {
        BinomialNode H = new BinomialNode();
        BinomialNode temp = H;
        if (H1 == null) // if it's the first insert
        {
            return H2;
        }
        while (H1 != null && H2 != null)
        {
            if (H1.degree < H2.degree)
            {
                // insert H1 into position
                temp.key = H1.key;
                temp.x_point = H1.x_point;
                temp.y_point = H1.y_point;
                temp.child = H1.child;
                temp.degree = H1.degree;
                temp.sibling = new BinomialNode();
                temp = temp.sibling;

                // move H1 to the next sibling
                H1 = H1.sibling;
            }
            else
            {
                // insert H2 into position
                temp.key = H2.key;
                temp.x_point = H2.x_point;
                temp.y_point = H2.y_point;
                temp.child = H2.child;
                temp.degree = H2.degree;
                temp.sibling = new BinomialNode();
                temp = temp.sibling;

                // move H2 to next sibling
                H2 = H2.sibling;
            }
        }

        // one of them hit null, so fill in the rest
        while (H1 != null)
        {
            // insert H1 into position
            temp.key = H1.key;
            temp.x_point = H1.x_point;
            temp.y_point = H1.y_point;
            temp.child = H1.child;
            temp.degree = H1.degree;
            temp.sibling = new BinomialNode();
            temp = temp.sibling;

            // move H1 to the next sibling
            H1 = H1.sibling;
        }
        while (H2 != null)
        {
            // insert H2 into position
            temp.key = H2.key;
            temp.x_point = H2.x_point;
            temp.y_point = H2.y_point;
            temp.child = H2.child;
            temp.degree = H2.degree;
            temp.sibling = new BinomialNode();
            temp = temp.sibling;

            // move H2 to the next sibling
            H2 = H2.sibling;
        }

        // To remove the extra node added,
        temp = H;
        while (temp != null)
        {
            if (temp.sibling.key == 0 && temp.sibling.sibling == null && temp.sibling.child == null)
            {
                // found the extra, now to get rid of it!
                temp.sibling = null;
            }
            temp = temp.sibling;
        }
        return H;  // send back the merged heap
    }

    // Unites the binomial heaps H1 & H2 and returns resulting heap
    public static BinomialNode Binomial_Heap_Union(BinomialNode H1, BinomialNode H2)
    {
        BinomialNode prev_x, x, next_x;
        BinomialNode H = new BinomialNode();
        H = Binomial_Heap_Merge(H1, H2);

        // simple checks
        if (H == null)
        {
            return H;
        }
        else
        {
            prev_x = null;
            x = H;
            next_x = x.sibling;
        }

        // now, for the actual merging
        while (next_x != null)
        {
            if ((x.degree != next_x.degree) || (next_x.sibling != null && x.degree == next_x.sibling.degree))
            {
                prev_x = x;
                x = next_x;
            }
            else if (x.key <= next_x.key)
            {
                x.sibling = next_x.sibling;
                Binomial_Link(ref next_x, ref x);
            }
            else
            {
                if (prev_x == null)
                {
                    H = next_x;
                }
                else
                {
                    prev_x.sibling = x.sibling;
                }
                Binomial_Link(ref x, ref next_x);
                x = next_x;
            }
            next_x = x.sibling;
        }

        // now, to return the merged heap
        return H; 
    }

    // inserting a key into a heap
    public static void Binomial_Heap_Insert(ref BinomialNode H, int x)
    {
        BinomialNode H_temp = new BinomialNode();
        H_temp.key = x;
        H_temp.parent = null;
        H_temp.degree = 0;
        H_temp.sibling = null;
        H_temp.child = null;
        H = Binomial_Heap_Union(H, H_temp);
    }
}

Uso una finestra del modulo per ottenere i dati dagli utenti per riempire l'heap. L'input è qui,

 private void button1_Click(object sender, EventArgs e)
        {
            BinomialNode.Binomial_Heap_Insert(ref B_HEAP1, Int32.Parse(numericUpDown1.Value.ToString()));

            // drawing the heap
            pictureBox1.Refresh();
            int x = 0;
            DrawNodeValue(pictureBox1, ref B_HEAP1, ref x, 0);
        }

Spero che il codice non sia troppo gravemente fatto?

È stato utile?

Soluzione

Stai creando un nuovo nodo e quindi copia tutti i valori. È quello che vuoi fare? Se ti aspetti di usare gli stessi nodi, usa gli stessi nodi.

Invece di:

Node H = new Node();
Node temp = H;
if(node1 > node2)
  temp.values = node1.values
else
  temp.values = node2.values

Basta usare gli oggetti reali ...

Node temp;
if(node1 > node2)
  temp = node1;
else
  temp = node2;

Non sono sicuro di dove si stiano separando i valori, ma è per questo che in realtà non sono lo stesso nodo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top