我必须从文件中读取数据包,然后按照block_num的顺序将数据包重建为链表。
struct packet {
unsigned short block_num;
unsigned short block_size;
unsigned short crc;
unsigned char *payload;
};
struct list {
struct packet p;
struct list *next;
};
这是我读取数据包并将其添加到链表中的代码,但是我如何根据block_num对它们进行排序?
FILE *infp;
struct list *head = NULL;
struct list *last = NULL;
while (fread(&p, sizeof(p), 1, infp) != NULL) {
packet *newpacket = malloc(sizeof(p));
struct list *newlist = malloc(sizeof(list));
newlist -> p = newpacket;
newlist -> next = NULL;
if (head == NULL) {
head = last = newlist;
} else {
last -> next = newlist;
last = newlist;
}
}
答案 0 :(得分:0)
您希望输出是一个链接列表,其成员按block_num排序。在这种情况下,为什么不将您的读取功能转换为智能读卡器。
逻辑如下:
`
for (cur = head; cur != end; cur = cur->next) {
if (cur->p->block_num <= newpacket->block_num &&
cur->next->p->block_num > newpacket->block_num) {
// insert newlist here
newlist->next = cur->next;
cur->next = newlist;
}
}
`
在上面的代码中,cur的类型为struct list *。
答案 1 :(得分:0)
您必须实现自己的排序,因为标准qsort()
仅适用于数组。我推荐merge sort。
您也可以使用数组而不是链接列表 - 然后您可以使用qsort()
。如果您不知道要读取的数据包数量,只需将数组的大小调整为每次填充时的两倍,并且您希望存储另一个数据包。然后,在末尾添加一个项目的摊销时间复杂度为O(1)。
答案 2 :(得分:0)
首先,你忘了在列表的新元素中复制你从文件中读取的内容,在malloc之后,你应该把:
*newpacket = p;
你应该在while循环之外声明newpacket。然后在链接列表中按顺序插入是以这种方式完成的(为简单起见,我只考虑了block_num,我从键盘而不是文件中获取它,并在按CTRL + D时停止):
unsigned int block_num;
struct list *newlist;
struct list *x, *t;
while(scanf("%u", &block_num) == EOF) {
newlist = (struct list *)malloc(sizeof(struct list));
newlist->p.block_num = block_num;
newlist->next = NULL;
if(head == NULL) {
/* empty list */
head = newlist;
last = newlist;
}
else {
if(head->p.block_num > newlist->p.block_num) {
/* insert as first element */
newlist->next = head;
head = newlist;
}
else {
t = head;
x = head->next;
while(x != NULL && x->p.block_num < newlist->p.block_num) {
t = x;
x = x->next;
}
/* insert */
t->next = newlist;
newlist->next = x;
if(x == NULL)
last = newlist;
}
}
}