Question

J'ai une classe avec la définition suivante,

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;
        ...
    }

Nous apprenons des tas binomiaux au collège et j'ai mis en œuvre la fusion et insérer des algorithmes dans le code. Au moins, quand je pause Visual Studio et passer sur les "habitants" (en volant la souris sur une variable), je vois les données comme je m'attends.

En tant qu'expérience, j'ai ajouté 2 variables supplémentaires au "nœud binomial standard". Ils sont x_point et y__point. Maintenant pendant l'exécution du programme, je vois ceci, Entrez la description de l'image ici

Veuillez noter la zone que j'ai indiquée ci-dessus. Il est censé représenter le même nœud, mais comme nous pouvons le constater, la valeur du point x_point est différente. (Dans d'autres cas, Y_Point est différent)

Quelqu'un a-t-il une idée de la raison pour laquelle cela se produit? Si je comprends bien, si cela représente le même nœud, les données doivent être identiques. Mais ce n'est pas - ce qui signifie que ce n'est pas le même noeud. Comment est-ce possible? Si j'ignore mes "variables extra" x_point et y_point, le code fonctionne parfaitement! En fait, je n'aurais même pas le savoir pour être un problème.

Ce n'est pas visible de mon extrait, mais X_Point & Y__Point sont les seules valeurs que je modifiez en dehors de la définition de la classe. Les autres, bien que le public ne soit que lu.

EDIT: Voici le code que j'ai fait,

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);
    }
}

J'utilise une fenêtre de formulaire pour obtenir les données des utilisateurs pour remplir le tas. L'entrée est ici,

 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);
        }

J'espère que le code n'est pas trop mal fait?

Était-ce utile?

La solution

Vous créez un nouveau nœud, puis vous copiez toutes les valeurs.Est-ce ce que vous voulez faire?Si vous prévoyez d'utiliser les mêmes nœuds, utilisez les mêmes nœuds.

au lieu de:

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

Utilisez simplement les objets réels ...

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

Je ne suis pas sûr où les valeurs sont séparées, mais c'est pourquoi ils ne sont pas réellement le même noeud.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top