排序链表

时间:2014-02-13 22:53:38

标签: c linked-list

我必须从文件中读取数据包,然后按照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;
    }
}

3 个答案:

答案 0 :(得分:0)

您希望输出是一个链接列表,其成员按block_num排序。在这种情况下,为什么不将您的读取功能转换为智能读卡器。

逻辑如下:

  1. 如果列表为空,请按照惯例进行操作,并将head和last all分配给newList。
  2. 如果列表不为空,请首先查看列表以查找当前对象的位置。在该点处理列表并连接节点。例如:
  3. `

    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;
        }
    }
}