这是代码的更新版本。每次客户端向服务器发送消息时,我都会尝试在链接列表中添加一些信息(它可以是多个客户端)。每次新消息到达时,该函数都会检查其时间,以便根据当前时间将其添加到上一个节点之前或之后的列表中。服务器必须按到达顺序打印消息。如果有相同的时间戳,那么它应该移动以使用服务器的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 :(得分:0)
问题不在于添加的打印代码。
在添加新节点时,您可能会分配节点,但不会将其连接到头部或任何其他节点。
您必须有这样的代码才能添加到列表的开头:
new_node->next = head;
head= new_node;
此外,您使用的逻辑是模糊的,并且您有许多代码重复。
添加到链接列表只有两个选项:列表的开头(头部)或任何其他节点,您不需要所有这些逻辑。
答案 1 :(得分:0)
只要至少有一个节点,打印列表的方式应该可以正常工作。我建议您将do { ... } while()
更改为仅while() { ... }
,以便在列表为空且head
为NULL
时仍然有效:
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升序,只需要进行一些更改。
修改的
由于找到节点的原始for
循环继续到符合条件的 last 节点,我们只需要在循环中添加一个测试,以便在我们处于正确状态时断开...也就是说,如果下一个节点具有相同的时间和更高的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;
}