从列表

时间:2017-05-12 18:07:24

标签: c list pointers singly-linked-list

我正在编写一个程序,用于创建列表,打印并从列表中删除(3个函数)。

打印和pushBack很好,它们工作得很好,但我无法弄清楚如何从removeFromList()函数中的列表中删除一个数字。

不要注意名称(如客户端,套接字),我的客户端 - 服务器应用程序要保存活动套接字(这就是我需要从列表中删除它们的原因)客户已断开连接)。

这里我有2个结构:listElement和clientList(包含指向listElement头元素的指针)

struct listElement
{
    SOCKET socket;
    struct listElement* next;
};

struct clientList
{
    listElement * head;
};

我的pushBack功能:

int pushBackСlient(struct clientList* list, int socket)
{
    struct listElement* newClient = (struct listElement*)malloc(sizeof(struct listElement));
    struct listElement* currentElement = list->head;
    newClient->socket = socket;
    newClient->next = 0;
    do
    {
        // IT'S PUSHBACK
        if (list->head == 0)
        {
            list->head = newClient;
            break;
        }
        while (currentElement->next != 0)
        {
            currentElement = currentElement->next;
        }
        currentElement->next = newClient;
    } while (false);

    return 0;
}

我的打印:

void print(struct clientList* list)
{
    struct listElement* currentElement = list->head;
    while (currentElement != 0)
    {
        printf("%d\n", currentElement->socket);
        currentElement = currentElement->next;
    }
}

我遇到问题的功能(我发了调试信息,看看" socket"是否正确添加)。我想我不需要前三行但不确定。

更新 13/05/2017

void removeFromList(struct clientList* list, int socket)
{
    struct listElement* currentElement = list->head;
    do
    {
        if (list->head == 0)
        {
            return;
        }

        while (currentElement != 0 && currentElement->next != 0)
        {
            if (currentElement->socket == socket)
            {
                printf("currentElement == %d\n", currentElement);
                currentElement = currentElement->next;
                printf("currentElement == %d\n", currentElement);
                free(currentElement);
                //break; // if I only want to remove the first socket?
            }
            currentElement = currentElement->next;
        }
    } while (false);
}

谢谢。

2 个答案:

答案 0 :(得分:4)

函数RestTemplate至少是错误的,因为当列表只包含一个元素时,while语句的这个条件可以等于false。在这种情况下,即使这一个元素也包含目标vakue,它也不会被删除。

removeFromList

这些功能可以看起来像示范程序中所示。

while (currentElement != 0 && currentElement->next != 0)

程序输出

#include <stdio.h>
#include <stdlib.h>

typedef int SOCKET;

struct listElement
{
    SOCKET socket;
    struct listElement *next;
};

struct clientList
{
    struct listElement *head;
};

int pushBackClient( struct clientList *list, SOCKET socket )
{
    struct listElement *newClient = malloc( sizeof( struct listElement ) );
    int success = newClient!= NULL;

    if ( success )
    {
        newClient->socket = socket;
        newClient->next   = NULL;

        struct listElement **current = &list->head;

        while ( *current != NULL ) current = &( *current )->next;

        *current = newClient;
    }

    return success;
}


int removeFromList( struct clientList *list, SOCKET socket )
{
    int success;

    struct listElement **current = &list->head;

    while ( *current != NULL && ( *current )->socket != socket ) 
    {
        current = &( *current )->next;
    }

    if ( ( success = *current != NULL ) )
    {
        struct listElement *tmp = *current;
        *current = ( *current )->next;

        free( tmp );
    }

    return success;
}

void print(struct clientList *list)
{
    for ( struct listElement *current = list->head;
          current != NULL;
          current = current->next )
    {         
        printf( "%d ", current->socket );
    }
}

int main(void) 
{
    const int N = 10;
    struct clientList list = { NULL };

    for ( int i = 0; i < N; i++ ) pushBackClient( &list, i );

    print( &list );
    putchar( '\n' );

    for ( int i = 0; i < N; i++ )
    {
        if ( i % 2 == 0 ) removeFromList( &list, i );
    }

    print( &list );
    putchar( '\n' );

    for ( int i = 0; i < N; i++ )
    {
        if ( i % 2 == 1 ) removeFromList( &list, i );
    }

    print( &list );
    putchar( '\n' );

    return 0;
}

您至少需要添加一个释放列表中所有元素的函数。

答案 1 :(得分:0)

对于你的删除功能,我建议这样的事情:

void removeFromList(struct clientList* list, int socket)
{
    struct listElement* aux, prev;
    if(list->head == 0)
        return;

    aux = list->head;
    prev = aux;

    while(aux != 0){
        if(aux->socket == socket) {
            prev->next = aux->next;
            free(aux);
            break; // if you only want to remove the first socket
        }
        prev = aux;
        aux = aux->next;    
    }
} 

至于你的列表结构,我建议使用结构的结构,如下所示:

struct list
{
    int numberOfElements;
    NODE * first;
} LIST;

struct node
{
    ELEMENT * info;
    NODE * prev; // If you want to have a double connection between the nodes
    NODE * next;
} NODE;

struct element
{
    int id;
    /* Other Properties */
} ELEMENT;

它可以让您更好地控制您的列表。