合并两个链表
Merging two linked lists
我有一个任务,我必须在不创建新列表的情况下按升序将 2 个链表组合到一个函数中。像这样:[1.3-->3.2-->4.6-->7.0]
& [2.7-->2.9-->5.1]
-> [1.3-->2.7-->2.9-->3.2-->4.6-->5.1-->7.0]
。我有完整的代码,但监控程序一直报告相同的内容:MEMORY LEAK
.
这是我的代码(只有函数部分,以及 struct
定义):
typedef struct _listelem {
double data;
struct _listelem *next;
} listelem;
listelem *merge(listelem *a, listelem *b) {
listelem *lemarado = NULL;
listelem *mozgo = a;
listelem *elol2 = b;
lemarado = mozgo;
if (elol2 == NULL) // if the list is zero
return a;
else
if (mozgo == NULL)
return b;
if (mozgo->next == NULL) { //if the first list has only one element
while (elol2 != NULL) {
listelem *vege;
vege = (listelem *)malloc(sizeof(listelem));
vege->data = elol2->data;
lemarado->next = vege;
free(vege);
lemarado = lemarado->next;
elol2 = elol2->next;
}
lemarado->next = NULL;
return a;
}
mozgo = mozgo->next; // I am maintaining a pointer which points to the next data, and a pointer
while (mozgo != NULL) { // Which points to the data before, and I stick an element between them
if (elol2 == NULL) {
while (mozgo != NULL)
mozgo = mozgo->next;
while (lemarado != NULL)
lemarado = lemarado->next;
return a;
}
if (mozgo->data > elol2->data) {
listelem *hozzafuz;
hozzafuz = (listelem *)malloc(sizeof(listelem));
hozzafuz->data = elol2->data;
lemarado->next = hozzafuz;
hozzafuz->next = mozgo;
elol2 = elol2->next;
lemarado = lemarado->next;
} else {
mozgo = mozgo->next;
lemarado = lemarado->next;
}
if (mozgo == NULL) {
while (elol2 != NULL) {
listelem *vege;
vege = (listelem *)malloc(sizeof(listelem));
vege->data = elol2->data;
lemarado->next = vege;
free(vege);
lemarado = lemarado->next;
elol2 = elol2->next;
}
lemarado->next = NULL;
}
}
return a;
}
无需分配空闲列表节点,您只需将已排序的列表合并为一个列表即可。使用非英语变量名会让不会说匈牙利语的人感到困惑,这恐怕很常见。
这是修改后的版本:
typedef struct _listelem {
double data;
struct _listelem *next;
} listelem;
listelem *merge(listelem *a, listelem *b) {
listelem *head = NULL;
listelem *tail = NULL;
if (b == NULL)
return a;
else
if (a == NULL)
return b;
if (a->data <= b->data) {
head = a;
a = a->next;
} else {
head = b;
b = b->next;
}
tail = head;
while (a != NULL && b != NULL) {
if (a->data <= b->data) {
tail->next = a;
a = a->next;
} else {
tail->next = b;
b = b->next;
}
tail = tail->next;
}
if (a == NULL)
tail->next = b;
else
tail->next = a;
return head;
}
如果你掌握了双指针,上面的代码可以简化为:
listelem *merge(listelem *a, listelem *b) {
listelem *head = NULL;
for (listelem **link = &head;; link = &(*link)->next) {
if (a == NULL) {
*link = b;
break;
}
if (b == NULL) {
*link = a;
break;
}
if (a->data <= b->data) {
*link = a;
a = a->next;
} else {
*link = b;
b = b->next;
}
}
return head;
}
struct thing *merge(struct thing *one,struct thing *two)
{
struct thing *result;
struct thing **pp; // will always point to the _pointer_ that will be assigned the next node.
result=NULL;
for(pp = &result; one && two; pp = &(*pp)->next) {
if(one->value <= two->value) {
*pp = one; one = one->next;
}
else {
*pp = two; two = two->next;
}
}
// When we get here, one and/or two will be NULL
*pp = (one) ? one : two;
return result;
}
我有一个任务,我必须在不创建新列表的情况下按升序将 2 个链表组合到一个函数中。像这样:[1.3-->3.2-->4.6-->7.0]
& [2.7-->2.9-->5.1]
-> [1.3-->2.7-->2.9-->3.2-->4.6-->5.1-->7.0]
。我有完整的代码,但监控程序一直报告相同的内容:MEMORY LEAK
.
这是我的代码(只有函数部分,以及 struct
定义):
typedef struct _listelem {
double data;
struct _listelem *next;
} listelem;
listelem *merge(listelem *a, listelem *b) {
listelem *lemarado = NULL;
listelem *mozgo = a;
listelem *elol2 = b;
lemarado = mozgo;
if (elol2 == NULL) // if the list is zero
return a;
else
if (mozgo == NULL)
return b;
if (mozgo->next == NULL) { //if the first list has only one element
while (elol2 != NULL) {
listelem *vege;
vege = (listelem *)malloc(sizeof(listelem));
vege->data = elol2->data;
lemarado->next = vege;
free(vege);
lemarado = lemarado->next;
elol2 = elol2->next;
}
lemarado->next = NULL;
return a;
}
mozgo = mozgo->next; // I am maintaining a pointer which points to the next data, and a pointer
while (mozgo != NULL) { // Which points to the data before, and I stick an element between them
if (elol2 == NULL) {
while (mozgo != NULL)
mozgo = mozgo->next;
while (lemarado != NULL)
lemarado = lemarado->next;
return a;
}
if (mozgo->data > elol2->data) {
listelem *hozzafuz;
hozzafuz = (listelem *)malloc(sizeof(listelem));
hozzafuz->data = elol2->data;
lemarado->next = hozzafuz;
hozzafuz->next = mozgo;
elol2 = elol2->next;
lemarado = lemarado->next;
} else {
mozgo = mozgo->next;
lemarado = lemarado->next;
}
if (mozgo == NULL) {
while (elol2 != NULL) {
listelem *vege;
vege = (listelem *)malloc(sizeof(listelem));
vege->data = elol2->data;
lemarado->next = vege;
free(vege);
lemarado = lemarado->next;
elol2 = elol2->next;
}
lemarado->next = NULL;
}
}
return a;
}
无需分配空闲列表节点,您只需将已排序的列表合并为一个列表即可。使用非英语变量名会让不会说匈牙利语的人感到困惑,这恐怕很常见。
这是修改后的版本:
typedef struct _listelem {
double data;
struct _listelem *next;
} listelem;
listelem *merge(listelem *a, listelem *b) {
listelem *head = NULL;
listelem *tail = NULL;
if (b == NULL)
return a;
else
if (a == NULL)
return b;
if (a->data <= b->data) {
head = a;
a = a->next;
} else {
head = b;
b = b->next;
}
tail = head;
while (a != NULL && b != NULL) {
if (a->data <= b->data) {
tail->next = a;
a = a->next;
} else {
tail->next = b;
b = b->next;
}
tail = tail->next;
}
if (a == NULL)
tail->next = b;
else
tail->next = a;
return head;
}
如果你掌握了双指针,上面的代码可以简化为:
listelem *merge(listelem *a, listelem *b) {
listelem *head = NULL;
for (listelem **link = &head;; link = &(*link)->next) {
if (a == NULL) {
*link = b;
break;
}
if (b == NULL) {
*link = a;
break;
}
if (a->data <= b->data) {
*link = a;
a = a->next;
} else {
*link = b;
b = b->next;
}
}
return head;
}
struct thing *merge(struct thing *one,struct thing *two)
{
struct thing *result;
struct thing **pp; // will always point to the _pointer_ that will be assigned the next node.
result=NULL;
for(pp = &result; one && two; pp = &(*pp)->next) {
if(one->value <= two->value) {
*pp = one; one = one->next;
}
else {
*pp = two; two = two->next;
}
}
// When we get here, one and/or two will be NULL
*pp = (one) ? one : two;
return result;
}