请求链接列表帮助

时间:2014-06-16 02:37:03

标签: c

这是我的链表结构:

typedef struct intervalo *Lista;

typedef struct intervalo
{
    int num;
    Lista next;
}Lista_int;

这是我的代码(我制作)中破坏列表的部分:

Lista destroi_lista_res(Lista lista)
{
    Lista temp_ptr;
    while (lista->next!= NULL)
    {
        temp_ptr = lista;
        lista= lista->next;
        free(temp_ptr);
    }
    free(lista);
    return NULL;
}

不幸的是,当调用此函数时,我的程序会挂起。具体来说,while (lista->next!= NULL)永远不会终止。

我的问题:为什么这一行导致无限循环?


其他代码详情:

在main()中,创建了两个列表。

/* Create linked list. */
Lista cria_lista_cab()
{
    Lista aux;
    aux=(Lista)malloc(sizeof(Lista_int));
    if(aux!=NULL)
    {
        aux->next=NULL;
    }
    return aux;
}

以下函数用于将数字节点添加到两个列表的末尾:

/* Insert node at the list tail. */
void insere_elem(Lista *lista,int num)
{
    Lista aux,ant_pos=*lista,pos=ant_pos->next;
    aux=(Lista)malloc(sizeof(Lista_int));
    while(pos!=NULL)
    {
        ant_pos=ant_pos->next;
        pos=pos->next;
    }
    aux->num=num;
    aux->next=pos;
    ant_pos->next=aux;
}

下一个函数组合了两个列表的数字节点,消除了重复数字增加的数字。返回结果列表:

Lista cria_lista_una(Lista lista1,Lista lista2)
{
    Lista lista_res=cria_lista_cab();
    lista1=lista1->next;
    lista2=lista2->next;
    while(lista1!=NULL && lista2!=NULL)
    {
        if(lista1->num<lista2->num)
        {
            insere_elem(&lista_res,lista1->num);
            printf("\n1 %d %d",lista1->num,lista2->num);
            if(lista1!=NULL)
                lista1=lista1->next;
        }
        else if(lista2->num<lista1->num)
        {
            insere_elem(&lista_res,lista2->num);
            printf("\n2 %d %d",lista1->num,lista2->num);
            if(lista2!=NULL)
                lista2=lista2->next;
        }
        else if(lista2->num==lista1->num)
        {
            printf("\n3 %d %d",lista1->num,lista2->num);
            if(lista1!=NULL)
                lista1=lista1->next;
            else if(lista2!=NULL)
                lista2=lista2->next;
        }
    }
    if(lista1!=NULL)
    {
        while(lista1!=NULL)
        {
            insere_elem(&lista_res,lista1->num);
            lista1=lista1->next;
        }
    }
    else if(lista2!=NULL)
    {
        while(lista2!=NULL)
        {
            insere_elem(&lista_res,lista2->num);
            lista2=lista2->next;
        }
    }
    return lista_res;
}

以下功能用于打印列表。

void imprime_lista_res(Lista lista)
{
    lista=lista->next;
    while(lista!=NULL)
    {
        printf("\nNum-> %d",lista->num);
        lista=lista->next;
    }
}

除了在调用destroi_lista_res()并且程序挂起时清理时,所有内容似乎都按预期运行。

3 个答案:

答案 0 :(得分:3)

这可能是因为lista开头为NULL。

将功能更改为:

Lista destroi_lista_res(Lista lista)
{
    Lista temp_ptr;
    while (lista!= NULL)
    {
        temp_ptr = lista;
        lista= lista->next;
        free(temp_ptr);
    }
    return NULL;
}

答案 1 :(得分:0)

给出你的代码:

void insere_elem(Lista *lista,int num)
{
    Lista aux,ant_pos=*lista,pos=ant_pos->next;
    aux=(Lista)malloc(sizeof(Lista_int));

并记住Lista实际上被定义为a 指向struct Lista_int

的实例的指针

您的代码变为: 注意:您实际将节点附加到链接列表,而不是插入

void insere_elem(struct Lista_int* *lista,int num) //note the ptr to ptr
{
    struct Lista_int * aux;
    struct Lista_int * ant_pos=*lista; //gets ptr to first instance of struct Lista_int
    struct Lista_int * pos=ant_pos->next; // get ptr to NULL or second instance of..

    // get ptr to new instance of struct
    aux=(struct Lista_int*)malloc(sizeof(Lista_int));

    // HERE should be checking that malloc() was successful
    // otherwise, the lines:
    //  aux->num=num;
    //  aux->next=pos;
    // will be writing to offsets from address 0 
    // will probably cause a crash


    // step forward through linked list to find last struct
    while(pos!=NULL)
    {
        ant_pos=ant_pos->next; // step ptr to prior struct
        pos=pos->next;         // step ptr to current struct
    }

    aux->num=num;  // set fields in new struct
    aux->next=pos; // pos is already NULL, so probably (for clarity) just use NULL
    ant_pos->next=aux; // set old struct instance ptr to new instance of struct
}

另外,关于这段代码:

while(lista2!=NULL)
{
    insere_elem(&lista_res,lista2->num);
    lista2=lista2->next;
}

此循环从链接列表'lista_res'的头部开始 因此,对于当前链表中的每个元素,它都会添加另一个元素 一般来说, 这意味着链接列表的大小加倍,每个条目都会进入此代码序列

答案 2 :(得分:0)

在你的distroi函数中,如果Lista已经为NULL,它会做什么,那么它将通过分段错误。但是根据你的说法,如果你要退出该功能,那么你可能无法正确创建列表。 首先进行如下更改:

Lista destroi_lista_res(Lista lista)
{
    Lista temp_ptr;
    while (lista!= NULL)
    {
        temp_ptr = lista;
        lista= lista->next;
        free(temp_ptr);
    }
    return NULL;
}

需要注意的另一件事是&#34;您是否正确创建了列表,如果是,那么您的打印功能将无法正常工作。为了确保这一点,请为调试目的制作一个虚拟遍历函数,它只是跟你在distroi函数中一样遍历列表。