I riferimenti non corrispondono
-
12-11-2019 - |
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,
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?
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.