Учитывая, что 2 отдельных списка уже отсортированы, объедините списки.Большая сложность для слияния двух списков
Пример:
песни1: 1 2 3 5 7
песни2: 0 4 6 7 10
---> 0 1 2 3 4 5 6 7 7 10
Несмотря из того, что решение довольно просто и есть несколько различных реализаций задачи с использованием или без использования рекурсии (как это http://www.geeksforgeeks.org/merge-two-sorted-linked-lists/ см Способ 3),
мне было интересно, что будет O большая сложность реализации этого:
- Если один из списков пуст просто возвращает другой
- В противном случае вставьте каждый узел второго списка в первом, используя функцию sortedInsert, которая в основном сканирование списка, пока правая позиция не найдена. Поскольку два списка уже отсортированы, нет необходимости сравнивать каждый раз, когда узел со всеми узлами в первом списке, я могу начать сравнение с последним добавленным узлом.
например: продолжается и в предыдущем примере, если 4 было уже добавлено могу смело начать следующее сравнение с 4:
песни1: песни2: 6-10
сейчас сравните 6 с 4 вместо этого с 1 2 3 4 ....
Если бы я сравнил один элемент со всеми элементами в первом списке, это было бы O (m * n) с m = # list2 и n = # list1, но учитывая эту «оптимизацию», какая сложность?
Реализация:
// Insert a new node in a sorted list
int sortedInsert(struct ListNode **head, struct ListNode* newNode) {
int headUpdated = 0;
struct ListNode *current;
// The list is empty or the new element has to be added as first element
if (*head == NULL || (*head)->data >= newNode->data) {
newNode->next = *head;
*head = newNode;
headUpdated = 1;
}
else {
// Locate the node before the point of insertion
current = *head;
while (current->next != NULL && current->next->data < newNode->data)
current = current->next;
newNode->next = current->next;
current->next = newNode;
}
return headUpdated;
}
struct ListNode *mergeLists(struct ListNode *head1, struct ListNode *head2) {
if (head1 == NULL)
return head2;
if (head2 == NULL)
return head1;
// Store the node in the first list where to start the comparisons
struct ListNode *first = head1;
while (head2) {
struct ListNode *head2Next = head2->next;
printf("Adding %d starting comparison from %d\n", head2->data, first->data);
if (sortedInsert(&first, head2))
head1 = first;
first = head2;
head2 = head2Next;
}
return head1;
}
@ H2CO3 Нет, каждое сравнение сопровождается либо вставкой, либо «current = current-> next». Существуют вставки 'n' и не более чем' m + n - 1'. –
Если вы сядете и выполните последовательность операций, вы увидите, что ваша версия эквивалентна стандартным слиянием списков, написанным по-разному. –
@ DanielFischer О, есть два фактора, правильно. Виноват. – 2013-05-12 04:19:56