2013-06-13 5 views
0

Я работал над созданием очереди и пытаюсь управлять ею. Мне нужна очередь для записи активных клиентов в приложении udp single server/multiple clients (я вынужден использовать udp, поэтому, пожалуйста, не предлагайте переходить на tcp).Удаление узла из очереди

Существует один сервер и количество клиентов. Всякий раз, когда клиент отправляет свое первое сообщение, номер ip и номер порта этого клиента push() ed в очередь.

Затем через каждые 5 секунд вызывается сервер pop() s 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. 
      } 
     } 
    } 



} 
+0

Не связано с вашим вопросом, правда, вы поступили не так с логикой в ​​'else' часть функции' push' ?? –

+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', правильно? И не должен« начинаться »с изменением до« хвоста »после поп-кода? Немного изменил код, для' head 'case, если это то, что я понял. –

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 отдельных случая - если удаляемый узел является головкой, если это хвост или если он находится между ними (обратите внимание, что вам понадобится чтобы обеспечить собственную функциональность для определения мертвого узла):

/* 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. Лучше использовать структуру данных связанных списков.

Смежные вопросы