How to trade two non-consecutive knots on a doubly chained list?

Asked

Viewed 786 times

3

I needed to switch two consecutive knots or not on a doubly linked list, but I can’t. Can someone help me? I’ve even done it on paper but it doesn’t perform. What’s wrong with the code?

void swap(no_teste* A, no_teste* B) {

    no_teste* proximoA = A->prox;
    no_teste* anteriorB = B->ant;

    A->prox = B->prox;
    B->ant = A->ant;

    A->ant = anteriorB;
    anteriorB->prox = A;
    B->prox = proximoA;
    proximoA->ant = B;

}

I get lost with this switch of pointers, if it were simply chained list I could. Someone can help me?

Those last ones I tried on paper but I couldn’t even use them:

void init(no_teste* aA, no_teste* A, no_teste* bA, no_teste* aB, no_teste* B, no_teste* bB) {
    aA = A->ant;
    bA = A->prox;
    aB = B->ant;
    bB = B->prox;
}

void Disconect_Geral_Node(no_teste* aA, no_teste* A, no_teste* bA) {

    aA->prox = NULL;
    A->ant = NULL;
    A->prox = NULL;
    bA->ant = NULL;

}

void Geral_Conect(no_teste* aA, no_teste* B, no_teste* bA) {
    aA->prox = B;
    B->ant = aA;
    B->prox = bA;
    bA->ant = B;
}
  • Switch hands prox and ant or change content just enough?

1 answer

3


In your code changes to B->prox and A->ant are not correct:

A->ant = anteriorB;
B->prox = proximoA;

For the former of A will become the B, and the next of B will become the A. In addition you do not need the temporary variables if you make the changes in the correct order.

As a first approach you can do so:

void swap(no_teste* A, no_teste* B) {
    A->ant->prox = B;
    B->prox->ant = A;
    A->prox = B->prox;
    B->ant = A->ant;
    B->prox = A;
    A->ant = B;
}

In this swap version I changed first before the A and then the next B and so it was not necessary to store values in temporary variables.

This solution will not work if the exchange is at the end of the list or at the beginning of the list because A->ant or B->prox evening NULL, which will result in a Segmentation fault. To solve it we have to test the NULL before changing:

void swap(no_teste* A, no_teste* B) {
    if (A->ant != NULL){
        A->ant->prox = B;
    }

    if (B->prox != NULL){
        B->prox->ant = A;
    }

    A->prox = B->prox;
    B->ant = A->ant;
    B->prox = A;
    A->ant = B;
}

Now despite not making a mistake the exchange at the beginning of the list will also not be correct because it would be necessary to change the head of the list, something that did not contemplate in the function header itself:

void swap(no_teste** lista, no_teste* A, no_teste* B) {
    if (A->ant != NULL){
        A->ant->prox = B;
    }
    else {
        *lista = B; //se A->ant é NULL, A é a cabeça e B passa agora a ser a cabeça
    }

    if (B->prox != NULL){
        B->prox->ant = A;
    }

    A->prox = B->prox;
    B->ant = A->ant;
    B->prox = A;
    A->ant = B;
}

Example of swaps in Ideone

In the ideone examples I used two show functions to be easy to see that both pointers ant as prox are correct.

I also considered that it was a double-linked list not circular.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.