C 从队列中删除节点

C 从队列中删除节点,c,queue,C,Queue,我一直在排队,并试图管理它。我需要一个队列来记录udp单服务器/多客户端应用程序中的活动客户端(我被迫使用udp,所以请不要建议切换到tcp) 有一台服务器和x个客户端。每当客户机发送其第一条消息时,该客户机的ip号和端口号就会被推送到队列中 然后,每隔5秒,服务器pop()将ip和端口号移出队列,并使用此ip和端口号向客户端发送消息。如果客户端在特定时间内回复,则认为它处于“活动”状态,但如果在超时时间内未收到来自客户端的报告,则认为该客户端已死亡,必须将其从队列中删除 现在的问题是如何删除这

我一直在排队,并试图管理它。我需要一个队列来记录udp单服务器/多客户端应用程序中的活动客户端(我被迫使用udp,所以请不要建议切换到tcp)

有一台服务器和x个客户端。每当客户机发送其第一条消息时,该客户机的ip号和端口号就会被推送到队列中

然后,每隔5秒,服务器pop()将ip和端口号移出队列,并使用此ip和端口号向客户端发送消息。如果客户端在特定时间内回复,则认为它处于“活动”状态,但如果在超时时间内未收到来自客户端的报告,则认为该客户端已死亡,必须将其从队列中删除

现在的问题是如何删除这个节点。一个选项是简单地添加NULL来代替这个节点,但我想从队列中完全删除这个节点

欢迎提出任何建议

下面是我的代码:

struct node
{
    int rollno;
    struct node*n;
};

struct node* create()
{
    struct node*q;
    q=(struct node*)malloc(sizeof(struct node));
    return q;
}
void push(struct node*cur)
{
    if(head==NULL)
    {
        head = cur;
        tail = cur;
        start = cur; //keeps a track of first node
    }
    else
    {
        struct node*f;
        f=head;
        head->n = cur;
        head=head->n; //keep updating head
    }
}

struct node* pop()
{
    struct node*p;
    struct node*s = NULL;p = tail;

    if (p == head && tail != head) /*if at the end of list, display starting from first element as Queue is FIFO*/
    {
        p = start;
        tail=p->n;
        s = p;
        display(s);
        return s;
    }

    if(p == NULL)
    {
        if (start == NULL)  //if no emelemt yet in the Queue
           return NULL;
        else // if at the End of list, go back to start
           {
              p = start;
              tail=p->n;
              s = p;
           }
    }
    else 
    {
           tail=p->n; //keep updating tail
           s = p;
    }

    display(s);
    return s;
}

void main()
{
   while(1)
   {
        //if new client
    struct node*j;  
    j = create();
        // j= ip and port of client.
    j->n=NULL;
        push(j); 
        //after every 5 secs
        {
           pop();
           //if client fails to reply
           {
              delete node.
           }
        }
   }



}

因为它是一个队列,所以删除只会发生在前面,这意味着您只需要去掉head元素。比如:

void delete()
{
    node* temp = head;  /* store the head the pointer so we can free it later */
    head = head->next;  /* make the node next to head be the head */
    free(temp);         /* free the original head pointer */
}
考虑到您的评论,如果我理解正确,您需要删除链接列表中的任何节点

这是一个针对链表中节点的删除功能,该功能处理三种不同的情况-如果要删除的节点是头节点、尾节点或中间节点(请注意,您需要提供自己的功能来识别死节点):


因为它是一个队列,所以删除只会发生在前面,这意味着您只需要去掉head元素。比如:

void delete()
{
    node* temp = head;  /* store the head the pointer so we can free it later */
    head = head->next;  /* make the node next to head be the head */
    free(temp);         /* free the original head pointer */
}
考虑到您的评论,如果我理解正确,您需要删除链接列表中的任何节点

这是一个针对链表中节点的删除功能,该功能处理三种不同的情况-如果要删除的节点是头节点、尾节点或中间节点(请注意,您需要提供自己的功能来识别死节点):


如果使用malloc函数为节点分配内存,则可以使用free函数释放该内存。这里没有为j指针分配内存,这是一个bug


在应用程序中,必须每5分钟检查一次每个元素是否处于活动状态,如果此时任何节点处于非活动状态,则必须将其删除。所以,我认为您不需要FIFO数据结构。最好使用链表数据结构。

如果使用malloc函数为节点分配内存,可以使用free函数释放该内存。这里没有为j指针分配内存,这是一个bug


在应用程序中,必须每5分钟检查一次每个元素是否处于活动状态,如果此时任何节点处于非活动状态,则必须将其删除。所以,我认为您不需要FIFO数据结构。最好使用链表数据结构。

正如DPG所说,链表更适合这里

现在,你需要这样的东西吗

void freenode(struct node* n)
{
    struct node* p = start;
    struct node* last = start;
    while (p != NULL) {
        if (p == n) {
            if (p == start) {
                if (p->n = NULL) {
                    head = NULL;
                    start = NULL;
                    tail = NULL;
            }
            else {
                if (tail == start)
                    tail = start->n;
                    start = start->n;
            }
            }
            else if (p == head) {
                head = last;
            head->n = NULL;
            }
            else {
                last->n = p->n;
            }
            free(p);
            break;
        }
        last = p;
        p = p->n;
    }
}

正如DPG所说,链表更适合这里

现在,你需要这样的东西吗

void freenode(struct node* n)
{
    struct node* p = start;
    struct node* last = start;
    while (p != NULL) {
        if (p == n) {
            if (p == start) {
                if (p->n = NULL) {
                    head = NULL;
                    start = NULL;
                    tail = NULL;
            }
            else {
                if (tail == start)
                    tail = start->n;
                    start = start->n;
            }
            }
            else if (p == head) {
                head = last;
            head->n = NULL;
            }
            else {
                last->n = p->n;
            }
            free(p);
            break;
        }
        last = p;
        p = p->n;
    }
}


虽然与您的问题无关,但您是否在函数中的
else
部分
push
?@Ayesha“完全删除”是什么意思?您想了解自由函数吗?如何创建新节点?没有看到新对象的任何内存分配,您所做的只是分配空值。另外,push和pop看起来很可疑,很像用于堆栈实现的东西,而不是队列。谢谢你的帖子。该代码可以很好地执行推送和删除操作popping@mohit,Ayesha:明白了。:-)与您的问题无关,您是否在函数中的
else
部分
push
?@Ayesha“完全删除”是什么意思?您想知道自由函数吗?您如何创建新节点?没有看到新对象的任何内存分配,您所做的只是分配空值。另外,push和pop看起来很可疑,很像用于堆栈实现的东西,而不是队列。谢谢你的帖子。该代码可以很好地执行推送和删除操作popping@mohit,Ayesha:明白了。:-)不,我认为只有当相应的客户端已死亡时才应该删除节点。她可以为此添加验证逻辑,但这基本上就是从队列中移除头的方式。在我看来,这不像队列(除了她在问题中提到这一点)。我想她想删除5秒后死亡的所有节点。是的,只有当相应的客户端死亡时,才应该删除该节点。好的,我已经添加了一些代码,根据该节点的id删除链接列表中的节点。我不知道如何识别哪个节点已死亡,但如果您知道,则此函数将帮助您删除它。如果不清楚,请告诉我。不,我认为只有在相应的客户端已死亡时才应该删除节点。她可以为此添加验证逻辑,但这基本上就是从队列中删除头的方式。在我看来,这不像队列(除了她在问题中提到这一点)。我想她想删除5秒后死亡的所有节点。是的,只有当相应的客户端死亡时,才应该删除该节点。好的,我已经添加了一些代码,根据该节点的id删除链接列表中的节点。我不知道如何识别哪个节点已死亡,但如果您知道,则此函数将帮助您删除它。如果不清楚,请告诉我。非常感谢。如果要删除的节点在中间,但如果要删除的节点是在队列的开头或结尾处,则它工作得很好:(请看一下,如果你能帮助我的话:(很抱歉,我有点困惑,向
头部
推了一下a,对吗?
开始
不应该在弹出后修改为
尾部