【发布时间】:2019-12-29 14:07:24
【问题描述】:
我应该创建一个函数来合并两个排序的单链表。
用户在控制台中输入两组数字,例如:5 3 1 0,组成一个链表,0表示该输入结束,不属于该链表。然后对列表进行排序,从最小值到最大值。排序后,列表的元素应该被一个一个地添加到一个新的列表中。最后,应该打印新创建的列表。
我尝试了很多不同的方法,但我最喜欢的一个是有两个不同的指向头的指针,所以 p 将是 head1 的指针,q 将是 head2 的指针。我从较小的 head 值开始,并将该 head 的指针移动到下一个元素。然后我记得我要在最后返回的节点的头部,然后进入 while 循环,从一个列表到另一个列表。
好的,我使用 S 将元素添加到我的新列表中,首先我从两个列表之间的较小数字开始,在本例中为 1 和第一个列表,只要我给 S 其值,我还将指针 p0 移动到下一个元素,所以现在它指向 3 (p1)。然后我把那个 S 作为我的新列表的头,然后进入 while 循环。在 while 循环中,我检查添加到新列表中的最后一个元素是来自第一个列表还是第二个列表,具体取决于结果,假设最后一个元素来自第一个列表(编号 1),我们移动到第二个清单。我让 S 指向 q1,然后 q 指向第二个列表 (q2) 的下一个元素,while 循环再次开始。该过程不断重复,直到两个指针之一为 NULL。在 while 循环之后,我有两个 if 语句(每个指针一个,以防它们指向 NULL),我返回另一个指针。希望现在它更清楚了。
typedef struct Element Element;
struct Element {
int data;
Element *next;
};
Element *addNew(int data) {
Element *newN = (Element*)malloc(sizeof(Element));
newN->data = data;
newN->next = NULL;
return newN;
}
Element *add_on_beginning(Element *head, Element *newN) {
newN->next = head;
return newN;
}
Element *add_on_end(Element *head, Element *newN) {
if (head == NULL) {
return newN;
}
Element *temp = head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newN;
return head;
}
void swap(Element *a, Element *b) {
int tempV;
tempV = a->data;
a->data = b->data;
b->data = tempV;
}
void sortList(Element *head) {
Element *temp;
int swapped;
do {
swapped = 0;
temp = head;
while (temp->next != NULL) {
if (temp->data > temp->next->data) {
swap(temp, temp->next);
swapped = 1;
}
temp = temp->next;
}
} while(swapped);
}
Element *merge(Element *head1, Element *head2, Element *newHead) {
Element *p = head1;
Element *q = head2;
Element *sort = NULL;
if (p == NULL) {
return q;
}
if (q == NULL) {
return p;
}
if (p != NULL && q != NULL) {
if (p->data <= q->data) {
sort = p;
p = sort->next;
} else {
sort = q;
q = sort->next;
}
}
newHead = sort;
while (p != NULL && q != NULL) {
if (sort->next == p->next) {
sort->next = q;
sort = q;
q = sort->next;
} else {
sort->next = p;
sort = p;
p = sort->next;
}
}
if (p == NULL) {
sort->next = q;
}
if (q == NULL) {
sort->next = p;
}
return newHead;
}
void printElement(Element *element) {
printf("%d ", element->data);
}
void printList(Element *head) {
Element *temp = head;
while (temp != NULL) {
printElement(temp);
temp = temp->next;
}
}
int main() {
Element *head = NULL;
Element *head2 = NULL;
Element *head3 = NULL;
char t;
int i;
char p;
int j;
printf("Input the first set of numbers: \n");
while (t != '\n') {
scanf("%d%c", &i, &t);
if (i == 0) {
break;
}
head = add_on_end(head, addNew(i));
}
printf("Input the second set of numbers: \n");
while (p != '\n') {
scanf("%d%c", &j, &p);
if (j == 0) {
break;
}
head2 = add_on_end(head2, addNew(j));
}
sortList(head);
sortList(head2);
head3 = merge(head, head2, head3);
printList(head3);
return 0;
}
我遇到的问题是合并,它打印出这两个排序但未与一个和另一个合并的列表,而不是它的第一个列表和第二个列表之后。
例如:
输入:
2 6 4 8 1
7 9 2 3 5
输出:
1 2 4 6 8 2 3 5 7 9
应该是:
输入:
2 6 4 8 1
7 9 2 3 5
输出:
1 2 2 3 4 5 6 7 8 9
【问题讨论】:
-
指针结构的大多数问题的答案是“拿起笔和纸,非常小心地玩自己的代码。”请报告该活动,即证明您进行了此类分析。
-
老实说,我做过很多次。一切看起来都不错。
-
然后做一些你认为列表指针在执行程序时如何发展的方框和箭头 ascii 艺术。也许使用较小的输入。
-
我刚刚编辑了我的帖子,希望它会更容易理解。
-
使用指向指针的指针通常是一种解决方案。 [而
merge()函数不需要第三个参数]
标签: c merge linked-list