@romajke

Как отсортировать двусвязный список SplDoublyLinkedList?

Есть двусвязный список который мне нужно отсортировать за O(n Log n) время. Я бы хотел использовать merge sort, но я никак не могу сообразить, как это реализовать путём расширения класса SplDoublyLinkedList из стандартной библиотеки PHP.

Основная проблема в том, что я не могу разделить SplDoublyLinkedList пополам без выделения дополнительной памяти. Если бы я имел объекты отдельных нод, я бы легко мог установить указатель next ноды из середины списка на null, и сохранить указатель на следующую ноду в отдельную переменную, таким образом получив уже два связных списка. Но SplDoublyLinkedList не позволяет провернуть такую операци.
Я имею ввиду нечто подобное в Java:
node mergeSort(node h) 
    { 
        if (h == null || h.next == null) { 
            return h; 
        } 

        node middle = getMiddle(h); 
        node nextOfMiddle = middle.next; 

        middle.next = null; 

        node left = mergeSort(h); 
        node right = mergeSort(nextofmiddle); 

        node sortedlist = sortedMerge(left, right); 
        return sortedlist; 
    }

Должен ли я действительно использовать SplDoublyLinkedList в этом случае, или мне лучше написать свою собственую реализацию связного списка?
  • Вопрос задан
  • 202 просмотра
Пригласить эксперта
Ответы на вопрос 2
LaRN
@LaRN
Senior Developer
Если нет возможности обращаться к элементу по индексу не выйдет уложиться в O(n Log n).
Т.к. по списку можно ходит только последовательно (перебирая все элементы до нужного), а не произвольно.
Может проще добавлять в список элементы так, чтобы они были отсортированы?
Ответ написан
wataru
@wataru Куратор тега Алгоритмы
Разработчик на С++, экс-олимпиадник.
Немного через одно место получается, но раз уж вам надо на php, до еще и с SplDoublyLinkedList, то...

Вы можете вместо одной операции разбиения списка просто в цикле откусывать элемент с конца, с помощью pop и добавлять в другой список с помощью push.

На n log n сложность это не повлияет. Просто замедлит ровно в 1.5-2 раза, в зависимости от реализации merge.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы