【问题标题】:Swapping single-linked list nodes creates an infinite loop交换单链表节点会创建一个无限循环
【发布时间】:2012-10-07 02:42:11
【问题描述】:

我的节点有一个整数值。我希望我的程序使用这样的值交换两个节点:

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

如您所见,我创建了六个变量。两个节点。每个节点之前的节点。以及每个节点之后的节点。

然后,我进行交换。

但是,当我尝试打印节点时,交换似乎会生成一个无限循环。

我的交换基于这个答案:https://stackoverflow.com/a/1536011/555690

EDIT:其他功能,根据要求:

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

【问题讨论】:

  • 你能具体说明 antecedentePorValor() 和 siguienteNodo() 的作用吗?因为在我看来,当函数结束时,所有变量都超出了范围。我本来希望在 remplazarNodosConValores() 中使用成员变量。
  • 添加了请求的功能
  • 你能添加一个产生错误的案例吗?

标签: c++ linked-list


【解决方案1】:

有几种情况你需要小心

  1. 值为b 的节点紧跟在值为a 的节点之后,反之亦然
  2. 值为ab 的节点是列表中的第一个节点
  3. a或值b的节点不止一个

如果没有看到函数antecedentePorValornodoPorValor 的代码,就无法说出您对案例2 还是3 有问题。案例 #1 有一个错误。

编辑:为了说明为什么 #1 存在错误,假设 node(a) 指向 node(b),然后

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!!
}

在 cmets 中,我使用简写 preva 表示 antecedenteDelPrimeroa 表示 primerob 表示 segundo

【讨论】:

  • 我添加了为什么 #1 有错误的解释
  • +1;我一定快疯了(或者累了……);我手动执行它并说服自己没有问题。谢谢你的解释。
猜你喜欢
  • 2016-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-24
  • 2021-05-14
  • 2010-12-04
相关资源
最近更新 更多