struct node
{
void *data;
struct node *prev;
struct node *next;
};
我也可以在O(1)时间内将元素插入到列表的末尾,因此我需要另一个
struct
来存储head
和tail
:struct linklist
{
struct node *head;
struct node *tail;
size_t size;
};
程序在所有插入和删除操作中都按预期运行,但是我在排序函数上遇到了问题。我正在使用归并排序算法,据我所知,这是排序列表最有效或最有效之一的方法。该算法能够很好地工作:
static struct node *split(struct node *head)
{
struct node *fast = head;
struct node *slow = head;
while ((fast->next != NULL) && (fast->next->next != NULL))
{
fast = fast->next->next;
slow = slow->next;
}
struct node *temp = slow->next;
slow->next = NULL;
return temp;
}
static struct node *merge(struct node *first, struct node *second, int (*comp)(const void *, const void *))
{
if (first == NULL)
{
return second;
}
if (second == NULL)
{
return first;
}
if (comp(first->data, second->data) < 0)
{
first->next = merge(first->next, second, comp);
first->next->prev = first;
first->prev = NULL;
return first;
}
else
{
second->next = merge(first, second->next, comp);
second->next->prev = second;
second->prev = NULL;
return second;
}
}
static struct node *merge_sort(struct node *head, int (*comp)(const void *, const void *))
{
if ((head == NULL) || (head->next == NULL))
{
return head;
}
struct node *second = split(head);
head = merge_sort(head, comp);
second = merge_sort(second, comp);
return merge(head, second, comp);
}
但是我不知道如何保持list->tail
地址的更新:
void linklist_sort(struct linklist *list, int (*comp)(const void *, const void *))
{
list->head = merge_sort(list->head, comp);
// list->tail is no longer valid at this point
}
当我想要更新 list->tail
时,我可以对列表进行排序并遍历整个列表来实现,但我想知道是否有更好的方法。
我成功地使用了循环列表来解决问题,但我想避免改变程序的结构。