2013-06-13 109 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數據結構。最好使用鏈表數據結構。