2013-06-13 69 views
0

我一直在做一个队列并试图管理它。我需要一个队列来记录我的udp单服务器/多客户端应用程序中的活动客户端(我不得不使用udp,因此请不要建议转移到tcp)。从队列中删除一个节点

有单个服务器和x个客户端。每当客户端发送其第一条消息时,该客户端的IP号码和端口号就被push()到队列中。

然后,在每隔5秒后,服务器pop()的IP和端口号从队列中发出,并使用此IP和端口号向客户端发送消息。如果客户端在特定的时间内回复,它被认为是“活动的”,但如果在超时时间内没有从客户端接收到repy,则客户端被认为是死的,并且必须从队列中移除。

现在的问题是如何删除这个节点。一种选择是简单地在此节点的位置添加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. 
      } 
     } 
    } 



} 
+0

虽然与你的问题没有关系,你是否在函数'push'的'else'部分出现了错误? –

+0

@Ayesha“完全删除”是什么意思?你想知道免费函数 - http://www.cplusplus.com/reference/cstdlib/free/ –

+0

你怎么创建一个新的节点呢?没有看到新对象的内存分配,只要分配NULL即可。 另外,push和pop看起来很像可以用于堆栈实现的东西,而不是队列。 – Nobilis

回答

1

正如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; 
    } 
} 
+0

非常感谢。如果要删除的节点在中间,但是如果要删除的节点位于队列的开始或结束处,它将无法正常工作:( – Ayse

+0

如果可以帮助我,请看看它:( – Ayse

+0

对不起,我有一点困惑,有人向'head'推了一下,对吗?在pop之后不应该'开始'修改为'tail'吗?修改一下代码,为'head如果这是我所理解的, –

1

,因为它意味着是一个队列,删除只在前面这意味着你只需要摆脱头部元件的发生。例如:

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 */ 
} 

考虑到您的评论,如果我理解正确,您需要删除链接列表中的任何节点。

这是一个链表中的节点的删除函数,用于处理三个3个独立的情况 - 如果要删除的节点是头部,是尾部还是介于两者之间(请注意,您需要提供自己的用于鉴定死者节点功能):如果你使用的malloc功能,为您的节点分配内存

/* need id argument to know which node needs to be deleted 
* we need to already know which node is dead */ 
void delete_arbitrary(int id) 
{ 
    if (head->rollno == id) /* id matches that of head, let's delete it */ 
    { 
     node* temp = head; /* store the head 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 */ 
    } 
    else /* node somewhere down the line, let's find it */ 
    { 
     node* curr = head->next /* start from the node after the head */ 
     node* prev; /* this is to keep track of the previous node */ 

     while(curr->rollno != id && curr != NULL) 
     { 
      prev = curr; 
      curr = curr->next; 
     } 

     if (curr == NULL) /* didn't find it so let's report it and quit */ 
     { 
      printf("Node not found\n"); 
     } 
     else if (curr->next == NULL) /* we're at the tail */ 
     { 
      node* temp = tail; /* store it for later deletion */ 
      tail = prev; /* the previous node is now the tail */ 
      free(temp); /* free the old tail */ 
     } 
     else /* it's somewhere in between */ 
     { 
      prev->next = curr->next; /* the previous node now points to the one after the current */ 
      free(curr); /* get rid of the current pointer */ 
     } 
    } 
} 
+1

不,我认为只有当相应的客户端已经死亡时才应该删除节点。 – mohit

+0

那么她可以为其添加验证逻辑,但这基本上是如何从队列中删除头部的。 – Nobilis

+0

这看起来不像队列给我(除了她在她的问题中提到这个)。我想她想要移除所有在5秒后死亡的节点。 – mohit

1

,可以释放使用免费功能的内存。这里你没有为j指针分配内存,这是一个错误。

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