我正在尝试对链表进行合并排序。
我保持我的头变量全局并应用基本算法,即分而治之。
我不明白为什么我会遇到分段错误。
我知道我可以通过传递头部作为参考来做到这一点,但我仍然需要知道为什么会发生这种情况。
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node *next;
};
Node *head;
void push(Node **head_ref, int x) {
Node *temp = new Node();
temp->next = *head_ref;
temp->data = x;
*head_ref = temp;
}
void split(Node *temp, Node **a, Node **b) {
Node *slow;
Node *fast;
slow = temp;
fast = temp->next;
while (fast != NULL) {
fast = fast->next;
if (fast != NULL) {
slow = slow->next;
fast = fast->next;
}
}
*a = temp;
*b = slow->next;
slow->next = NULL;
}
Node *mergesort(Node *a, Node *b) {
if (a == NULL) {
return b;
} else
if (b == NULL) {
return a;
}
if (a->data < b->data) {
a->next = mergesort(a->next, b);
return a;
} else {
b->next = mergesort(a, b->next);
return b;
}
}
void merge(Node **head_ref) {
Node *head = *(head_ref);
Node *a;
Node *b;
if (head == NULL || head->next == NULL) {
return;
}
split(head, &a, &b);
merge(&a);
merge(&b);
head = mergesort(a, b);
}
void print(Node *n) {
while (n != NULL) {
cout << n->data << " ";
n = n->next;
}
}
我的主要方法如下:
int main() {
Node *head;
push(&head, 1);
push(&head, 3);
push(&head, 6);
push(&head, 4);
push(&head, 2);
print(head);
merge(&head);
cout << endl;
print(head);
}
代码中有一些简单的错误:
-
head
被定义为全局变量,但在main
中也被定义为局部变量,所以这个局部变量在main
内部使用,而不是全局变量。确实不需要全局变量。 -
main()
中的局部变量Node *head;
未初始化。所有push
调用都将成功,构造一个由head
指向的列表,但在1
之后next
节点有一个未定义的指针,print
尝试取消引用此指针时将崩溃。行为未定义,您可能偶然出现在head
中空指针,但您可能具有无效指针,从而导致未定义的行为。将head
初始化为NULL
:Node *head = NULL;
-
在
merge
结束时,你不会通过head_ref
更新头部指针,所以调用方中的变量不会更新。写这个:*head_ref = mergesort(a, b);
请注意,merge
接收Node *head
指针并返回更新的Node *
头指针会更简单。
另请注意,您的函数名称令人困惑:merge
应该命名为mergesort
,反之亦然。
这是一个修改版本:
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node *next;
};
void push(Node **head_ref, int x) {
Node *temp = new Node();
if (temp) {
temp->next = *head_ref;
temp->data = x;
*head_ref = temp;
}
}
void split(Node *temp, Node **a, Node **b) {
Node *slow = temp;
Node *fast = temp->next;
while (fast != NULL) {
fast = fast->next;
if (fast != NULL) {
slow = slow->next;
fast = fast->next;
}
}
*a = temp;
*b = slow->next;
slow->next = NULL;
}
Node *merge(Node *a, Node *b) {
if (a == NULL) {
return b;
}
if (b == NULL) {
return a;
}
if (a->data <= b->data) {
a->next = merge(a->next, b);
return a;
} else {
b->next = merge(a, b->next);
return b;
}
}
Node *mergesort(Node *head) {
Node *a;
Node *b;
if (head == NULL || head->next == NULL) {
return head;
}
split(head, &a, &b);
a = mergesort(a);
b = mergesort(b);
return merge(a, b);
}
void print(const Node *n) {
while (n != NULL) {
cout << n->data << " ";
n = n->next;
}
count << endl;
}
int main() {
Node *head = NULL;
push(&head, 1);
push(&head, 3);
push(&head, 6);
push(&head, 4);
push(&head, 2);
print(head);
head = mergesort(head);
print(head);
return 0;
}