Я немного теряюсь, пытаясь понять, как рекурсивно объединить сортировку моего связанного списка. Я пытался следовать некоторым руководствам, но я немного теряюсь со всеми указателями и рекурсией. Такое ощущение, что проблема в функции слияния, когда списки имеют по одному узлу.
У меня есть класс Node
и класс списка. Я упустил другие функции-члены, чтобы сделать его более читабельным. Вот классы. Извините, некоторые имена переменных не являются лучшими в функциях.
class Node {
public:
int val;
Node *next;
};
class Linked_list {
private:
unsigned int length;
Node *head;
Node *tail;
public:
void sort_ascending();
void merge_sort(Node **);
void halve(Node *&, Node *&, Node *&);
Node* merge(Node *, Node *);
};
Я начинаю с sort_ascending()
, который создает указатель Node
и устанавливает его на первый узел в списке, а затем вызывает merge_sort
с указателем в качестве параметра.
void Linked_list::sort_ascending() {
Node *h = head->next;
merge_sort(&h);
}
merge_sort
проверяет, являются ли первые два индекса NULL
, возвращает, если они есть. В противном случае связанный список делится пополам.
void Linked_list::merge_sort(Node **h) {
Node *t = *h;
Node *a;
Node *b;
if ((t == NULL) || (t->next == NULL)) {
return;
}
halve(t, a, b);
merge_sort(&a);
merge_sort(&b);
*h = merge(a, b);
return;
}
Здесь приведена функция разбиения списка на две половины.
void Linked_list::halve(Node *&t, Node *&a, Node *&b) {
Node *h1 = t;
Node *h2 = t->next;
while (h2 != NULL) {
h2 = h2->next;
if (h2 != NULL) {
h1 = h1->next;
h2 = h2->next;
}
}
a = t;
b = h1->next;
h1->next = NULL;
}
Наконец, функция слияния.
Node *Linked_list::merge(Node *a, Node *b) {
Node *h = NULL;
if (a == NULL) {
return b;
}
if (b == NULL) {
return a;
}
if (a->val <= b->val) {
h = a;
h->next = merge(a->next, b);
} else {
h = b;
h->next = merge(a, b->next);
}
return h;
}
Когда я запускаю свою программу и ввожу / печатаю несколько значений, я получаю:
9 4 32 2 6
Затем, когда я сортировать это, вывод становится:
9 4 2 6 32