Это вопрос по программированию, который задают во время письменного теста на собеседовании. «У вас есть два односвязных списка, которые уже отсортированы, вы должны объединить их и вернуть заголовок нового списка без создания каких-либо новых дополнительных узлов. Возвращенный список также должен быть отсортирован»
Сигнатура метода: Node MergeLists (Node list1, Node list2);
Класс узла ниже:
class Node{
int data;
Node next;
}
Я пробовал много решений, но не создавал лишних узлов. Пожалуйста помоги.
Вот сопроводительная запись в блоге http://techieme.in/merging-two-sorted-singly-linked-list/
algorithm
singly-linked-list
дхарам
источник
источник
Ответы:
источник
Рекурсия не требуется, чтобы не выделять новый узел:
источник
if (list1.next == null) list1.next = list2;
может просто бытьlist1.next = list2;
. Посколькуwhile (list1.next != null)
цикл только что завершился, мы можем быть уверены в этомlist1.next == null
.источник
Вот алгоритм объединения двух отсортированных связанных списков A и B:
Здесь C будет выходным списком.
источник
Смотри, мама, без рекурсии!
источник
Итерацию можно выполнить, как показано ниже. Сложность = O (n)
источник
источник
Это можно было бы сделать без создания дополнительного узла, просто передав в параметры ссылку на другой узел (временный узел).
источник
Я хотел бы поделиться своим мнением о решении ... я видел решение, которое включает в себя рекурсию, и они довольно удивительны, это результат хорошо функционального и модульного мышления. Я очень ценю обмен.
Хочу добавить, что при больших размерах рекурсия не работает, вызовы стека будут переполняться; поэтому я решил попробовать итеративный подход ... и вот что я получил.
Код довольно понятен, я добавил несколько встроенных комментариев, чтобы убедиться в этом.
Если вы его не поняли, сообщите мне, и я улучшу читаемость (возможно, у меня неверная интерпретация моего собственного кода).
}
источник
Простое итеративное решение.
источник
Ниже я показываю итеративное решение. Рекурсивное решение было бы более компактным, но, поскольку мы не знаем длины списков, рекурсия может привести к переполнению стека.
Основная идея аналогична шагу слияния в сортировке слиянием; мы храним указатель, соответствующий каждому входному списку; на каждой итерации мы продвигаем указатель, соответствующий меньшему элементу. Однако есть одно важное отличие, когда большинство людей спотыкаются. При сортировке слиянием, поскольку мы используем массив результатов, следующей вставляемой позицией всегда является индекс массива результатов. Для связанного списка нам нужно сохранить указатель на последний элемент отсортированного списка. Указатель может перемещаться от одного входного списка к другому в зависимости от того, какой из них имеет меньший элемент для текущей итерации.
При этом следующий код не требует пояснений.
источник
Простой код в javascript для объединения двух связанных списков на месте.
источник
Прежде всего поймите, что означает «без создания дополнительных узлов». Насколько я понимаю, это не означает, что у меня не может быть указателя (ов), который указывает на существующий узел (ы).
Вы не можете добиться этого, не говоря указатели на существующие узлы, даже если вы используете рекурсию для достижения того же, система создаст для вас указатели в виде стеков вызовов. Это похоже на указание системе добавить указатели, которых вы избегали в своем коде.
Простая функция для достижения того же с помощью дополнительных указателей :
источник
Пожалуйста, обратитесь к моему сообщению в блоге для http://www.algorithmsandme.com/2013/10/linked-list-merge-two-sorted-linked.html
источник
источник
Вот полный рабочий пример, который использует связанный список, реализованный java.util. Вы можете просто скопировать и вставить приведенный ниже код в метод main ().
источник
Рекурсивный способ (вариант ответа Стефана)
Рассмотрим ниже связанный список, чтобы визуализировать это
2>4
список A1>3
список BПочти такой же ответ (не рекурсивный), что и Стефан, но с немного большим количеством комментариев / значимого имени переменной. Также в комментариях есть двусвязный список, если кому-то интересно
Рассмотрим пример
5->10->15>21 // List1
2->3->6->20 //List2
источник
Я подхожу к вопросу следующим образом:
Псевдокод:
Код:
источник
источник
источник
:) GlbMP
источник
public static Node merge(Node h1, Node h2) { Node h3 = new Node(0); Node current = h3; boolean isH1Left = false; boolean isH2Left = false; while (h1 != null || h2 != null) { if (h1.data <= h2.data) { current.next = h1; h1 = h1.next; } else { current.next = h2; h2 = h2.next; } current = current.next; if (h2 == null && h1 != null) { isH1Left = true; break; } if (h1 == null && h2 != null) { isH2Left = true; break; } } if (isH1Left) { while (h1 != null) { current.next = h1; current = current.next; h1 = h1.next; } } if (isH2Left) { while (h2 != null) { current.next = h2; current = current.next; h2 = h2.next; } } h3 = h3.next; return h3; }
источник
Вначале я создал только один фиктивный узел, чтобы избавить себя от множества условий «если».
источник
источник
источник
Вот код того, как объединить два отсортированных связанных списка headA и headB:
источник