简体   繁体   中英

Swapping single-linked list nodes creates an infinite loop

My nodes have an integer value. And I want my program to swap two nodes by using such value:

void reemplazarNodosConValores(int a,int b) {
    node *antecedenteDelPrimero = antecedentePorValor(a);
    node *antecedenteDelSegundo = antecedentePorValor(b);
    node *primero = nodoPorValor(a);
    node *segundo = nodoPorValor(b);
    node *nextDelPrimero = siguienteNodo(primero);
    node *nextDelSegundo = siguienteNodo(segundo);


    antecedenteDelSegundo->next = primero;
    primero->next = nextDelSegundo;

    antecedenteDelPrimero->next = segundo;
    segundo->next = nextDelPrimero;
}

As you can see, I create six variables. The two nodes. The nodes before each one. And the nodes after each one.

Then, I do the swap.

However, swapping seem to generate an infinite loop when I try to print my nodes.

I based my swaps on this answer: https://stackoverflow.com/a/1536011/555690

EDIT : The other functions, as requested:

node *antecedentePorValor(int x) {
    node *resultado = NULL;
    for (int i = 0; i < counter; ++i) {
        resultado = siguienteNodo(resultado);
        if (siguienteNodo(resultado)) {
            if (siguienteNodo(resultado)->data == x) {
                break;
            }
        }
    }
    return resultado;
}

node *nodoPorValor(int x) {
    node *resultado = head;
    for (int i = 1; i < counter; ++i) {
        if (resultado->data == x) {
            break;
        }
        resultado = resultado->next;
    }
    return resultado;
}

node *siguienteNodo(node *nodo) {
    node *resultado;
    if (nodo) {
        resultado = nodo->next;
    }else{
        resultado = head;
    }
    return resultado;
}

There are several cases you need to be careful with

  1. The node with value b immediately follows the node with value a or vice-versa
  2. The node with value a or b is the first node in the list
  3. There is more than one node with value a or value b

Not possible to say whether you have a problem with case 2 or 3 without seeing the code for the functions antecedentePorValor and nodoPorValor . There is a bug with case #1.

Edit: to show why there is a bug with #1, assume node(a) points to node(b), then

void reemplazarNodosConValores(int a,int b) {
    node *antecedenteDelPrimero = antecedentePorValor(a); // node preceding a
    node *antecedenteDelSegundo = antecedentePorValor(b); // node preceding b (a)
    node *primero = nodoPorValor(a);                      // node that contains a
    node *segundo = nodoPorValor(b);                      // node that contains b
    node *nextDelPrimero = siguienteNodo(primero);        // node following a (b)
    node *nextDelSegundo = siguienteNodo(segundo);        // node following b


    antecedenteDelSegundo->next = primero; // a->next = a
    primero->next = nextDelSegundo;        // a->next = node following b

    antecedenteDelPrimero->next = segundo; // preva->next = b
    segundo->next = nextDelPrimero;        // b->next = b <<== b points to self!!
}

In the comments I used shorthand preva to mean antecedenteDelPrimero and a to mean primero and b to mean segundo .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM