在@4386427提出建议后,我将我的问题更改如下。 在尝试合并两个列表时,我使用双指针来存储最终列表,并使用单指针来指向头节点。
trav->next
代替&((*trav)->next)
?mergedList->next
和 (*mergedList).next
(*mergedList).next
和&((*trav)->next)
如何在第一次迭代中为我提供相同的值?#include <stdio.h>
#include <stdlib.h>
#define DUMP_VALUES \
printf("&trav: %p, ", (void*)&trav); \
printf("trav: %p, ", (void*)trav); \
printf("*trav: %p, ", (void*)*trav); \
printf("(**trav).data: %d, ", (**trav).data); \
printf("&mergedList: %p, ", (void*)&mergedList); \
printf("mergedList: %p, ", (void*)mergedList); \
printf("(*mergedList).data: %d, ", (*mergedList).data); \
printf("&((*trav)->next): %p, ", (void *) &((*trav)->next)); \
printf("&((*trav).next): %p, ", (void *) &((*trav)->next)); \
printf("mergedList->next: %p, ", (void *) mergedList->next); \
printf("&((*mergedList).next): %p\n", (void *) &((*mergedList).next));
typedef struct Node {
int data;
struct Node *next;
}Node;
Node *createNode(int data) {
Node *newNode = (Node *) malloc(sizeof(Node));
if(!newNode) {
printf("mem-alloc failed for data: %d\n", data);
exit(EXIT_FAILURE);
}
newNode->data = data;
newNode->next = NULL;
return newNode;
}
Node *mergeTwoSortedLists(Node *head1, Node *head2) {
Node *mergedList = NULL;
Node **trav = &mergedList;
if(!head1 && !head2) {
printf("Both the heads are NULL, cant merge\n");
return NULL;
}
while (head1 && head2) {
if(head1->data <= head2->data) {
*trav = createNode(head1->data);
DUMP_VALUES;
head1 = head1->next;
}
else {
*trav = createNode(head2->data);
DUMP_VALUES;
head2 = head2->next;
}
trav = &((*trav)->next);
}
/* insertion of the remaining list to the trav
or insert the list that is not null. */
while (head1) {
*trav = createNode(head1->data);
DUMP_VALUES;
head1 = head1->next;
trav = &((*trav)->next);
}
while (head2) {
*trav = createNode(head2->data);
DUMP_VALUES;
head2 = head2->next;
trav = &((*trav)->next);
}
return mergedList;
}
void createSortedList(Node **head, int data) {
Node *trav = NULL;
Node *newNode = (Node *) malloc(sizeof(Node));
if(!newNode) {
printf("Memalloc failed - No memory allocated for data: %d\n", data);
return;
}
newNode->data = data;
if(!(*head) || (*head)->data >= data) {
newNode->next = *head;
*head = newNode;
return;
}
trav = *head;
while((trav->next) && (trav->next->data < data)) {
trav = trav->next;
}
newNode->next = trav->next;
trav->next = newNode;
return;
}
void printList(Node *head) {
if(!head) {
printf("Node is empty\n");
return;
}
while(head) {
printf("%d\t", head->data);
head = head->next;
}
printf("\n");
return;
}
int main() {
Node *head = NULL;
Node *head2 = NULL;
Node *head3 = NULL;
createSortedList(&head, 3);
createSortedList(&head, 5);
createSortedList(&head, 7);
createSortedList(&head, 3);
createSortedList(&head, 4);
createSortedList(&head, 9);
printList(head);
createSortedList(&head2, 10);
createSortedList(&head2, 5);
createSortedList(&head2, 9);
createSortedList(&head2, 4);
printList(head2);
head3 = mergeTwoSortedLists(head, head2);
printList(head3);
return 0;
}
输出:
PS C:\Users\preet\OneDrive\Desktop\preethiC\VSCode> gcc -Wall .\FirstProg.c
PS C:\Users\preet\OneDrive\Desktop\preethiC\VSCode> .\a.exe
3 3 4 5 7 9
4 5 9 10
&trav: 0061FEE8, trav: 0061FEEC, *trav: 00AE17C8, (**trav).data: 3, &mergedList: 0061FEEC, mergedList: 00AE17C8, (*mergedList).data: 3, &((*trav)->next): 00AE17CC, &((*trav).next): 00AE17CC, mergedList->next: 00000000, &((*mergedList).next): 00AE17CC
&trav: 0061FEE8, trav: 00AE17CC, *trav: 00AE17D8, (**trav).data: 3, &mergedList: 0061FEEC, mergedList: 00AE17C8, (*mergedList).data: 3, &((*trav)->next): 00AE17DC, &((*trav).next): 00AE17DC, mergedList->next: 00AE17D8, &((*mergedList).next): 00AE17CC
&trav: 0061FEE8, trav: 00AE17DC, *trav: 00AE17E8, (**trav).data: 4, &mergedList: 0061FEEC, mergedList: 00AE17C8, (*mergedList).data: 3, &((*trav)->next): 00AE17EC, &((*trav).next): 00AE17EC, mergedList->next: 00AE17D8, &((*mergedList).next): 00AE17CC
&trav: 0061FEE8, trav: 00AE17EC, *trav: 00AE17F8, (**trav).data: 4, &mergedList: 0061FEEC, mergedList: 00AE17C8, (*mergedList).data: 3, &((*trav)->next): 00AE17FC, &((*trav).next): 00AE17FC, mergedList->next: 00AE17D8, &((*mergedList).next): 00AE17CC
&trav: 0061FEE8, trav: 00AE17FC, *trav: 00AE1808, (**trav).data: 5, &mergedList: 0061FEEC, mergedList: 00AE17C8, (*mergedList).data: 3, &((*trav)->next): 00AE180C, &((*trav).next): 00AE180C, mergedList->next: 00AE17D8, &((*mergedList).next): 00AE17CC
&trav: 0061FEE8, trav: 00AE180C, *trav: 00AE1818, (**trav).data: 5, &mergedList: 0061FEEC, mergedList: 00AE17C8, (*mergedList).data: 3, &((*trav)->next): 00AE181C, &((*trav).next): 00AE181C, mergedList->next: 00AE17D8, &((*mergedList).next): 00AE17CC
&trav: 0061FEE8, trav: 00AE181C, *trav: 00AE1828, (**trav).data: 7, &mergedList: 0061FEEC, mergedList: 00AE17C8, (*mergedList).data: 3, &((*trav)->next): 00AE182C, &((*trav).next): 00AE182C, mergedList->next: 00AE17D8, &((*mergedList).next): 00AE17CC
&trav: 0061FEE8, trav: 00AE182C, *trav: 00AE1838, (**trav).data: 9, &mergedList: 0061FEEC, mergedList: 00AE17C8, (*mergedList).data: 3, &((*trav)->next): 00AE183C, &((*trav).next): 00AE183C, mergedList->next: 00AE17D8, &((*mergedList).next): 00AE17CC
&trav: 0061FEE8, trav: 00AE183C, *trav: 00AE6A70, (**trav).data: 9, &mergedList: 0061FEEC, mergedList: 00AE17C8, (*mergedList).data: 3, &((*trav)->next): 00AE6A74, &((*trav).next): 00AE6A74, mergedList->next: 00AE17D8, &((*mergedList).next): 00AE17CC
&trav: 0061FEE8, trav: 00AE6A74, *trav: 00AE69F0, (**trav).data: 10, &mergedList: 0061FEEC, mergedList: 00AE17C8, (*mergedList).data: 3, &((*trav)->next): 00AE69F4, &((*trav).next): 00AE69F4, mergedList->next: 00AE17D8, &((*mergedList).next): 00AE17CC
3 3 4 4 5 5 7 9 9 10
PS C:\Users\preet\OneDrive\Desktop\preethiC\VSCode>
您的打印声明是错误的。
如果您没有从编译器收到任何警告,则需要提高警告级别。例如,对于
gcc
使用选项:-Wall -Wextra -Werror -pedantic
打印指针时(即
%p
),您需要将指针强制转换为空指针。喜欢:
int x;
int* p = &x;
printf("p equals %p\n", (void*)p);
^^^^^^^
cast to void*
更糟糕的是
**trav
属于 Node
类型,但您使用 %d
打印它。您可能想打印 (**trav).data
。
和
*mergedList
类似。再次是 Node
,但这次您使用 %p
打印它。也许您想要 %d
和 (*mergedList).data
。
所有这些都意味着你的程序有未定义的行为。例如,请注意打印
&mergedList: 00000000
。这都是错误的。局部变量的地址不能是 00000000
。
请尝试:
printf("&trav: %p trav: %p, *trav: %p, **trav: %d, &mergedList: %p, mergedList: %p, *mergedList: %d\n", (void*)&trav, (void*)trav, (void*)*trav, (**trav).data, (void*)&mergedList, (void*)mergedList, (*mergedList).data);
也就是说,我建议您避免这么长的
printf
声明。将其分解为许多更简单的语句。喜欢:
printf("&trav: %p, ", (void*)&trav);
printf("trav: %p, ", (void*)trav);
printf("*trav: %p, ", (void*)*trav);
printf("(**trav).data: %d, ", (**trav).data);
printf("&mergedList: %p, ", (void*)&mergedList);
printf("mergedList: %p, ", (void*)mergedList);
printf("(*mergedList).data: %d\n", (*mergedList).data);
更容易阅读。更容易确保事情正确。
由于您执行了 4 次相同的打印,因此您可以考虑使用宏来避免多次输入相同的内容。
#define DUMP_VALUES \
printf("&trav: %p, ", (void*)&trav); \
printf("trav: %p, ", (void*)trav); \
printf("*trav: %p, ", (void*)*trav); \
printf("(**trav).data: %d, ", (**trav).data); \
printf("&mergedList: %p, ", (void*)&mergedList); \
printf("mergedList: %p, ", (void*)mergedList); \
printf("(*mergedList).data: %d\n", (*mergedList).data)
然后要打印,只需写:
DUMP_VALUES;
完成这些更改后,我的系统打印:
3 3 4 5 7 9
4 5 9 10
&trav: 0x7ffea69fcb20, trav: 0x7ffea69fcb28, *trav: 0x2134160, (**trav).data: 3, &mergedList: 0x7ffea69fcb28, mergedList: 0x2134160, (*mergedList).data: 3
&trav: 0x7ffea69fcb20, trav: 0x2134168, *trav: 0x2134180, (**trav).data: 3, &mergedList: 0x7ffea69fcb28, mergedList: 0x2134160, (*mergedList).data: 3
&trav: 0x7ffea69fcb20, trav: 0x2134188, *trav: 0x21341a0, (**trav).data: 4, &mergedList: 0x7ffea69fcb28, mergedList: 0x2134160, (*mergedList).data: 3
&trav: 0x7ffea69fcb20, trav: 0x21341a8, *trav: 0x21341c0, (**trav).data: 4, &mergedList: 0x7ffea69fcb28, mergedList: 0x2134160, (*mergedList).data: 3
&trav: 0x7ffea69fcb20, trav: 0x21341c8, *trav: 0x21341e0, (**trav).data: 5, &mergedList: 0x7ffea69fcb28, mergedList: 0x2134160, (*mergedList).data: 3
&trav: 0x7ffea69fcb20, trav: 0x21341e8, *trav: 0x2134200, (**trav).data: 5, &mergedList: 0x7ffea69fcb28, mergedList: 0x2134160, (*mergedList).data: 3
&trav: 0x7ffea69fcb20, trav: 0x2134208, *trav: 0x2134220, (**trav).data: 7, &mergedList: 0x7ffea69fcb28, mergedList: 0x2134160, (*mergedList).data: 3
&trav: 0x7ffea69fcb20, trav: 0x2134228, *trav: 0x2134240, (**trav).data: 9, &mergedList: 0x7ffea69fcb28, mergedList: 0x2134160, (*mergedList).data: 3
&trav: 0x7ffea69fcb20, trav: 0x2134248, *trav: 0x2134260, (**trav).data: 9, &mergedList: 0x7ffea69fcb28, mergedList: 0x2134160, (*mergedList).data: 3
&trav: 0x7ffea69fcb20, trav: 0x2134268, *trav: 0x2134280, (**trav).data: 10, &mergedList: 0x7ffea69fcb28, mergedList: 0x2134160, (*mergedList).data: 3
3 3 4 4 5 5 7 9 9 10
这比 OP 的结果更有意义。