2011-10-27 87 views
0

这是代码的更新版本。我试图在链接列表中添加一些信息,每次客户端发送消息到服务器(它可以是多个客户端)。每次有新消息到达时,函数会检查其时间,以便可以根据当前时间将其添加到前一个节点之前或之后的列表中。服务器必须按照到达顺序打印消息。如果有相同的时间戳记,那么它应该移动到使用服务器的ID来排序相同的时间戳记。链接列表的打印内容仅打印第一个节点

这里是我的列表结构:

'typedef struct trade_list { 
    char* trader_msg; 
    u_int32_t id_of_sender; 
    int sender_timer; 
    int local_time; 

    struct trade_list *next; 
}trade_list; 

trade_list *head = NULL; 

以下是插入根据时间来列出和排序功能:

void add_transaction (char* received_msg_IN, int curr_time_IN, u_int32_t my_id_IN, int elapsedIn) 
{ 
/* Find the node with the smallest time >= curr_time_IN. 'found' starts as NULL, then 
     is always the node before 'cur'. 'cur' moves through the list until its time is 
     less than 'curr_time_IN'. So at the end, 'cur' is the first node that's too 
     far in, and 'found' is either NULL or the node we insert after. */ 

    trade_list *newnode, *cur, *found; 


    found = NULL; 
    for (cur = head; cur && cur->sender_timer <= curr_time_IN; cur = cur->next) 
    found = cur; 


    if (found) { 
     /* If 'found' isn't NULL, we're inserting after it*/ 
      /* Times match: Sort out in another way*/ 

     } else { 
      newnode = malloc(sizeof(*newnode)); 
      newnode->trader_msg = malloc(strlen(received_msg_IN)*sizeof(received_msg_IN)); 
      strcpy(newnode->trader_msg,received_msg_IN); 
      newnode->sender_timer = curr_time_IN; 
      newnode->id_of_sender = my_id_IN; 
      newnode->local_time = elapsedIn; 
      newnode->next = found->next; 
      found->next = newnode; 

      } 
    } else {     

     /* No node with more recent time found -- inserting at 'head' */ 
     newnode = malloc(sizeof(*newnode)); 
     newnode->trader_msg = malloc(strlen(received_msg_IN)*sizeof(received_msg_IN)); 
     strcpy(newnode->trader_msg,received_msg_IN); 
     newnode->sender_timer = curr_time_IN; 
     newnode->id_of_sender = my_id_IN; 
     newnode->local_time = elapsedIn; 
     newnode->next = head; 
     head = newnode; 
     } 

修改之后的新的问题

我设法使用排序方法对列表进行排序,而不是稍后。所以现在我的列表得到很好的排序。它的打印效果非常好,现在出现的新问题是我想在打印后删除当前节点。所以打印后它会被删除。我使用了以下功能,但我的应用程序崩溃。

void deletefirst (struct trade_list *head) { 
    struct trade_list *tmp = *head;   
    if (tmp == NULL) return;    
    *head = tmp->next;     
    free (tmp);       
} 

我从我的打印功能调用这个函数:

void print_trades() 
{ 

    trade_list * newnode = head; 

     while (newnode) { 

      if ((elapsed - newnode->local_time >= 8)) 
      { 
      printf ("%s\n", newnode->trader_msg); 
      newnode = newnode->next; 
      deletefirst(newnode); 
      } 

      } 
} 

我怎么会删除当前节点,继续前进?

回答

0

您打印的清单应该正常工作,只要有至少一个节点的方式。我建议改变do { ... } while()只是一个while() { ... }虽然如此,它仍然工作当列表为空,headNULL

trade_list *currentnode = head; 
while (currentnode) { 
    printf ("Trade: %s Time: %d ID: %d\n", 
     currentnode->trader_msg, 
     currentnode->sender_timer, 
     currentnode->id_of_sender); 
    currentnode = currentnode->next; 
} 

有一些问题与您添加到列表的方式,虽然。当head不为空,你删除它链接到你的列表中的其他:

if (head == NULL) 
    { 
    ... /* skipped for brevity */ 
    } 
else 
    { 
    currentnode->next = NULL; 
    head = currentnode; 
    } 

因为在这一点上currentnode == head,你指着head->next为NULL(如果有另一个节点,你会扔掉它),然后分配head自己。一般

你插入的代码看起来不正确的。如果你只想在列表的开头插入,你只需要像:

trade_list *newnode = malloc(sizeof(trade_list)); 
/* *** Fill out newnode's fields here *** */ 
newnode->next = head; 
head = newnode; 

如果你想要一个任意节点之后插入,你必须要找到它首先通过遍历列表,然后做一些事情

trade_list *newnode, *cur, *found; 
/* Find the node with the smallest time >= curr_time_IN. 'found' starts as NULL, then 
    is always the node before 'cur'. 'cur' moves through the list until its time is 
    less than 'curr_time_IN'. So at the end, 'cur' is the first node that's too far in, 
    and 'found' is either NULL or the node we insert after. */ 
found = NULL; 
for (cur = head; cur && cur->sender_timer >= curr_time_IN; cur = cur->next) 
    found = cur; 

if (found) { 
    /* If 'found' isn't NULL, we're inserting after it (or skipping if the times match, 
    since that seems to be what the original code was trying to do) */ 
    if (found->sender_timer == curr_time_IN) { 
    /* Times match: skip it */ 
    printf("SKIPPED\n"); 
    } else { 
    /* inserting after 'found' */ 
    newnode = malloc(sizeof(*newnode)); 
    /* *** Fill out newnode's fields here *** */ 
    newnode->next = found->next; 
    found->next = newnode; 
    } 
} else { 
    /* No node with more recent time found -- inserting at 'head' */ 
    newnode = malloc(sizeof(*newnode)); 
    /* *** Fill out newnode's fields here *** */ 
    newnode->next = head; 
    head = newnode; 
} 

编后评论:像这样(在列表的头保管稍后的时间)

要更改列表排序按时间递减,然后通过ID上升时的时间匹配,只是一些变化s是必要的。

编辑 由于原for循环找到节点继续符合标准的最后节点,我们只需要一个测试加入到环打破,当我们处在正确的。也就是说,如果下一个节点具有相同的时间和更高的ID,则会中断,因为在那种情况下,我们想要在之前插入它。 (之前的编辑有缺陷......对此抱歉)。

此外,if (found->sender_timer == curr_time_IN)之后的检查不再需要,因为没有跳过,并且按ID排序由新的for循环处理。

这样的代码段成为:

/* original search */ 
for (cur = head; cur && cur->sender_timer >= curr_time_IN; cur = cur->next) { 
    /* *** added condition for ID sort */ 
    if (cur->sender_timer == curr_time_IN && cur->id_of_sender >= my_id_IN) break; 
    found = cur; 
} 

if (found) { 
    /* If 'found' isn't NULL, we're inserting after it */ 

    /* CHANGED: no need to skip when times are equal */ 
    newnode = malloc(sizeof(*newnode)); 
    /* *** Fill out newnode's fields here *** */ 
    newnode->next = found->next; 
    found->next = newnode; 

} else { 
    /* No node with more recent time found -- inserting at 'head' */ 
    newnode = malloc(sizeof(*newnode)); 
    /* *** Fill out newnode's fields here *** */ 
    newnode->next = head; 
    head = newnode; 
} 
+0

感谢您的帮助,真的很感激。这或多或少是我想要的。如果时间匹配而不是跳过它们,我想进一步检查发件人ID,以便正确分类。我没有在我之前的代码中加入。 –

+0

再次感谢,只是想问问你另一个问题,如果那样可以。如果我使用这一行“if(found-> sender_timer == curr_time_IN)”当我通过检查ID号码匹配时间来排列列表时,我该怎么办? 我以为我可以使用这样的:如果 如果(发现 - > sender_timer == curr_time_IN) { (发现 - > id_of_sender < cur-> id_of_sender)) ,但我无法弄清楚如何将其事后排序。任何帮助,再次非常感谢! –

+0

编辑说明如何将ID添加到排序中。顺便说一句,您还应该考虑使函数参数的类型与列表项中相应字段的类型匹配。 – Dmitri

0

问题与打印代码不符。

它看起来添加新节点时,像你这样的分配节点,但不把它连接到头部或任何其他节点。

你必须有这样的代码添加到列表的开头:

new_node->next = head; 
head= new_node; 

此外,您使用的逻辑是模糊的,你有很多的代码重复。

添加到链表只有两种选择:列表(头)的开始或者在任何其他节点的,你并不需要所有这种逻辑。

+0

谢谢,我把它做你所说的话,并通过消除工作的if语句我有比较。但是现在我无法比较,我有什么想法可以将节点与前一个节点进行比较,并且如果消息时间在交​​换节点之前? –