我目前正在开发一个项目,该项目接收带有数据的两个文本文件,并将它们分成两个单独的链接列表。我的下一步是创建一个函数,该函数接收这两个列表,按ID递增顺序对它们进行合并和排序。我已经开始实现了但是我很困难,需要一些指导我对合并排序函数做错了什么。其他所有工作正常,例如单独排序每个列表。我只需要一种方法来接受这两个列表并在C中合并它们。注意:我使用的是Ubuntu gcc编译器。
struct List *merge_list(struct List *list1, struct List *list2)
{
struct Node *hand1 = list1->head;
struct Node *hand2 = list2->head;
struct Node *tmp1, *tmp2 = NULL;
struct List *list3 = malloc(sizeof(struct List));
while(list1 && list2 != NULL)
{
if(ptr1->id > ptr2->id)
{
ptr1 = list3->head;
ptr1 = ptr1->next;
}
else
{
ptr2 = list3->head;
ptr2 = ptr2->next;
}
}
return list3;
}
注意:这是我的节点和列表结构
struct Node {
int id;
char *fname;
char *lname;
char *department;
float gpa;
struct Node *next;
struct Node *prev;
};
struct List {
struct Node *head;
struct Node *tail;
int count;
};
答案 0 :(得分:0)
合并两个排序列表:
while (hand1 && hand2) {
if (hand1->id <= hand2->id) {
tmp = hand1;
hand1 = hand1->next;
} else {
tmp = hand2;
hand2 = hand2->next;
}
insertNode(list3, tmp);
}
// either hand1 or hand2 will have some leftover elements
// they can be added to the back of list by inserting the head
if (hand1)
insertNode(list3, hand1);
else
insertNode(list3, hand2);
我已经给你写了insertNode()。为了保留两个列表的排序,它应该在列表的末尾插入节点。由于您正在跟踪列表的尾部,因此应该非常容易。
我会将list3中的指针初始化为NULL并将计数初始化为0,它应该使insertNode()更容易编写。
答案 1 :(得分:0)
您有两个双向链表并且两者都已排序,您的要求是创建一个函数,该函数接收这两个列表以按递增顺序按ID进行合并和排序。由于双向链表都已经排序,因此您不需要先将它们合并然后排序,但可以按排序顺序合并它们。
你可以这样做:
struct Node * merge_list(struct Node * head1, struct Node * head2)
{
struct Node* head3 = NULL;
struct Node* p1 = head1;
struct Node* p2 = head2;
struct Node* p3 = NULL;
while (p1 != NULL || p2 != NULL)
{
struct Node * tmp = NULL;
if (p1 == NULL) {
tmp = p2;
p2 = NULL;
} else if (p2 == NULL) {
tmp = p1;
p1 = NULL;
}
if ((p1 != NULL) && (p2 != NULL)) {
if (p1->id < p2->id) {
tmp = p1;
p1 = p1->next;
} else {
tmp = p2;
p2 = p2->next;
}
}
if (head3 == NULL) {
head3 = tmp;
} else {
p3->next = tmp;
tmp->prev = p3;
}
p3 = tmp;
}
return head3;
}
输出:
List 1:
1 3 7
List 2:
2 4 6 8
Merged list:
1 2 3 4 6 7 8
关于merge_list()
功能的几点:
merge_list()
函数中,我将获取列表的head
个指针,并返回合并列表的head
指针。但我可以看到你struct List
维护了列表的head
和tail
指针。因此,您需要在函数中相应地进行更改,例如参数和返回类型将是struct List *
类型,并且在函数中,您还需要处理合并列表tail
指针。核心逻辑将是相同的。merge_list()
修改两个列表,它们作为参数传递给它,因为它重置列表节点的next
和prev
指针以便合并它们。因此,在此函数调用之后,作为参数传递的列表都不再有效。将他们的head
和tail
指针设置为NULL
。merge_list()
调用之后将列表作为参数传递给merge_list()
,则需要在添加到合并列表时复制节点。为此,您需要将内存分配给tmp
以及将tmp
设置为p1
或p2
的位置,而是将值分配给tmp
成员。在这里要小心,如果结构Node
的成员是指向某个内存的指针,那么将内存分配给该tmp
成员指针并复制该值。希望这有帮助。