【问题标题】:C - Insertion in Linked List overwrite the valuesC - 链表中的插入覆盖值
【发布时间】:2020-05-21 10:52:10
【问题描述】:

我在属于二叉搜索树的节点中输入了一个链表,该链表遵循以下结构(不包含不涉及任何问题的元素):

// BINARY SEARCH TREE
typedef struct Equipo {
    char nombre[50];
    // [...]
    Lista *pilotos;
    struct nodo *izquierdo;
    struct nodo *derecho;
} Equipo;

typedef Equipo Arbol;

// LINKED LIST
typedef struct Piloto {
    int dorsal;
    // [....]
} Piloto;

typedef struct Nodo { 
    struct Piloto piloto;
    struct Nodo *siguiente;
} Nodo;

typedef struct Lista {
    Nodo *cabeza;
    int longitud;
} Lista;

为了在链表中插入新的Pilotos,我使用了在列表的初始化处插入的函数:

void InsertarCabezaLista(Lista *l, Piloto *piloto) {
    Nodo *n = CrearNodo(piloto); 
    n->siguiente = l->cabeza; 
    l->cabeza = n;
    l->longitud++;
}

为了插入一个Equipo,它使用了以下函数:

Equipo* CrearEquipo(Equipo *e) {
    Equipo *n = (Equipo *)malloc(sizeof(Equipo));
    strncpy(n->nombre, e->nombre, 50);
    strncpy(n->marcaMoto, e->marcaMoto, 30);
    n->puntuaciones = 0;
    n->derecho = n->izquierdo = NULL;
    return n;
}

void InsertarEquipo(Equipo **arbol, Equipo *e) {
    if (*arbol == NULL) {
        Equipo *n = CrearEquipo(e);
        *arbol = n;
    } else {
        // Los elementos menores a la izq, los elementos
        // mayores a la der.
        int comparado = strncmp(e->nombre, (*arbol)->nombre, 50);
        if (comparado > 0) {
            InsertarEquipo(&(*arbol)->izquierdo, e);
        } else {
            InsertarEquipo(&(*arbol)->derecho, e);
        }
    }
}

如您所见,插入的方式不同,因为Equipo 属于二叉搜索树,Piloto 属于链表。

main我创建了二叉搜索树的2个节点(Equipo):

Equipo *equipo = (Equipo *)malloc(sizeof(Equipo));
strcpy(equipo->nombre, "Ducati Team"); 
strcpy(equipo->marcaMoto, "Ducati"); 
equipo->puntuaciones = 0;
Arbol *arbol = CrearEquipo(equipo);

strcpy(equipo->nombre, "Repsol Honda Team"); 
strcpy(equipo->marcaMoto, "Honda"); 
equipo->puntuaciones = 0;
InsertarEquipo(&arbol, equipo);

然后,链表的 3 个节点 (Piloto) 并将 Piloto 按名称从 Equipo 插入到 Equipo 中:

Piloto *piloto = malloc(sizeof(piloto));

piloto->dorsal = 99;
strcpy(piloto->apellido, "Lorenzo");
InsertarPilotoEquipo(arbol, "Ducati Team", piloto);

piloto->dorsal = 93;
strcpy(piloto->apellido, "Márquez");
InsertarPilotoEquipo(arbol, "Repsol Honda Team", piloto);

piloto->dorsal = 26;
strcpy(piloto->apellido, "Pedrosa");
InsertarPilotoEquipo(arbol, "Repsol Honda Team", piloto);

piloto->dorsal = 27;
strcpy(piloto->apellido, "Wallon");
InsertarPilotoEquipo(arbol, "Repsol Honda Team", piloto);

如您所见,树 Ducati Team 中的 Equipo 有 1 个 PilotoRepsol Honda Team 有 3 个 Piloto

这个使用的函数,叫做InsertarPilotoEquipo是:

int InsertarPilotoEquipo(Equipo *arbol, char nombre[], Piloto *p) {
    if (!arbol) {
        return 0;
    } 
    Equipo *equipo = ObtenerEquipo(arbol, nombre);

    if (equipo) {
        equipo->pilotos = malloc(sizeof(equipo->pilotos));
        InsertarCabezaLista(equipo->pilotos, p);
        equipo->puntuaciones += p->puntuacion;
        return 1;
    } else {
        return 0;
    }
}

没有执行错误。但是当我从 Tree 获取信息时,我得到:

----------------------------
Nombre: Ducati Team
Moto: Ducati
Puntuacón: 46
Pilotos: 1
----------------------------

  Dorsal: 99
  Nombre: Lorenzo
  Puntuacón: 46


----------------------------
Nombre: Repsol Honda Team
Moto: Honda
Puntuacón: 204
Pilotos: 1
----------------------------

  Dorsal: 27
  Nombre: Wallon
  Puntuacón: 68

如我们所见,只记录最后一个Piloto 在树节点中。看起来它在树中每个节点的每次调用时都会被覆盖。

为了排除打印问题,我展示了打印数据的函数:

void BusquedaPreOrder(Equipo *arbol) {
    if (arbol) {
        printf("\n\t\t----------------------------");
        printf("\n\t\tNombre: %s", arbol->nombre);
        printf("\n\t\tMoto: %s", arbol->marcaMoto);
        printf("\n\t\tPuntuacón: %d", arbol->puntuaciones);
        printf("\n\t\tPilotos: %d", arbol->pilotos->longitud);
        printf("\n\t\t----------------------------");
        for (int i = 0; i < arbol->pilotos->longitud; i++) {
            ImprimirPiloto(i, arbol->pilotos);
        }

        printf("\n");
        BusquedaPreOrder(arbol->izquierdo);
        BusquedaPreOrder(arbol->derecho);
    }
}

它被BusquedaPreOrder(arbol);简单地调用。

我认为问题在于每个InsertPilotoEquipo 函数中的equipo-&gt;pilotos = malloc(sizeof(equipo-&gt;pilotos)); 调用,按树。但我不知道为什么或解决方案是什么。

【问题讨论】:

  • 很难看出其根本原因。但是,可能有两个可能的错误。 1. 看看你是如何打印数据的。也许列表是正确的,但打印有问题。 2. 你似乎对 Equipo 结构很满意。因此,您可以将 InsertarEquipo 与 InsertarPilotoEquipo 进行比较,看看是否发现链表中的任何差异。我看到你这里没有包括 InsertarEquipo。
  • 我已经用你错过的功能更新了帖子@diaco。如您所见,在打印数据时,我只是对每个元素及其嵌套列表进行迭代;参数arbol-&gt;pilotos-&gt;longitud表示列表的长度,在每个InsertarCabezaLista中用l->longitud++;`行增加。

标签: c linked-list malloc binary-search-tree


【解决方案1】:

最后我解决了这个问题,检查树列表是否被初始化;如果它没有被初始化并且如果它继续它(在每次调用时将它初始化为新的之前):

int InsertarPilotoEquipo(Equipo* arbol, char nombre[], Piloto* p) {
    if (!arbol) {
        return 0;
    } 
    Equipo* equipo = ObtenerEquipo(arbol, nombre);
    // ImprimirEquipo(equipo);
    if (equipo) {
        if (!equipo->pilotos) {
            equipo->pilotos  = malloc(sizeof(equipo->pilotos));
        }  
        InsertarCabezaLista(equipo->pilotos, p);
        equipo->puntuaciones += p->puntuacion;
        return 1;
    } else {
        return 0;
    }
}

【讨论】:

    猜你喜欢
    • 2014-11-27
    • 2019-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-10
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    相关资源
    最近更新 更多