Вставить узел в связанный список в постоянное время?

Я работаю над заданием, в котором мне предлагается предположить, что у меня есть односвязный список с заголовочными и хвостовыми узлами. Он хочет, чтобы я вставил элемент y перед позицией p. Кто-нибудь может взглянуть на мой код и сказать, на правильном ли я пути? Если нет, не могли бы вы дать мне какие-нибудь советы или подсказки (без каламбура)?

tmp = new Node();
tmp.element = p.element;
tmp.next = p.next;
p.element = y;
p.next = tmp;

Я думаю, что могу ошибаться, потому что я вообще не использую заголовочные и хвостовые узлы, хотя они специально упоминаются в описании проблемы. Я думал написать цикл while для обхода списка до тех пор, пока он не найдет p и таким образом решит проблему, но это не будет постоянным временем, не так ли?

Должна ли позиция p быть индексом или указателем / ссылкой на конкретный узел в списке?

Alnitak 16.11.2008 22:17

что на самом деле меня тоже смутило, проблема очень расплывчата и не уточняется. Он просто говорит: «Вставьте элемент y перед позицией p»

101010110101 16.11.2008 22:23

Предполагая, что p является указателем на узел, вы почти у цели. Иногда в этих вопросах содержится дополнительная информация, но в данном конкретном случае вам придется кое-что сделать с головой и / или хвостом ...

Blair Conrad 16.11.2008 22:47
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
3
8 197
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Ответ принят как подходящий

Просто запишите это, если вы застряли с алгоритмом:

// First we have a pointer to a node containing element (elm) 
// with possible a next element.
// Graphically drawn as:
// p -> [elm] -> ???

tmp = new Node();
// A new node is created. Variable tmp points to the new node which 
// currently has no value.
// p   -> [elm] -> ???
// tmp -> [?]

tmp.element = p.element;

// The new node now has the same element as the original.
// p   -> [elm] -> ???
// tmp -> [elm]

tmp.next = p.next;

// The new node now has the same next node as the original.
// p   -> [elm] -> ???
// tmp -> [elm] -> ???

p.element = y;

// The original node now contains the element y.
// p   -> [y] -> ???
// tmp -> [elm] -> ???

p.next = tmp;

// The new node is now the next node from the following.
// p   -> [y] -> [elm] -> ???
// tmp -> [elm] -> ???

У вас есть необходимый эффект, но он может быть более эффективным, и я уверен, что теперь вы можете выяснить это сами.

Понятнее написать что-то вроде:

tmp = new Node();
tmp.element = y;
tmp.next = p;
p = tmp;

Что, конечно, не работает, если p неизменяемый. Но ваш алгоритм не работает, если p == NULL.

Но я хотел сказать, что если у вас есть проблемы с алгоритмом, просто запишите эффекты. Особенно с деревьями и связанными списками, вы должны быть уверены, что все указатели указывают в правильном направлении, иначе вы получите большой беспорядок.

подожди, так что, наверное, я немного запутался. Когда я делаю tmp.element = p.element, я не просто уравниваю данные значений, содержащиеся в узлах, я также заставляю указатели указывать на то же самое?

101010110101 16.11.2008 22:16

или я неправильно понимаю вашу визуализацию

101010110101 16.11.2008 22:18

Я перепечатал, чтобы показать эффекты. Но я думаю, что это вызывает больше путаницы, чем разъяснения, поэтому я добавляю немного больше текста.

Toon Krijthe 16.11.2008 22:38

Намекать: вставка в связанный список постоянна только тогда, когда позиция п = 0 или заголовок списка. В противном случае сложность наихудшего случая равна На). Это не означает, что вы не можете создать достаточно эффективный алгоритм, но он всегда будет иметь линейную сложность по меньшей мере.

Не правда. В связанном списке можно сохранить как указатель головы, так и указатель хвоста. В этом случае возможна вставка O (N) в начало и конец списка.

JaredPar 16.11.2008 22:21

@JaredPar - разве вы не имеете в виду O (1)?

Alnitak 16.11.2008 22:24

@JaredPar: сложность наихудшего случая все равно будет O (n)

Federico A. Ramponi 16.11.2008 22:39

Если у вас есть ссылка на точку до или после предполагаемой вставки, вы всегда можете сделать постоянное время. Вот почему важен вопрос, является ли p индексом или указателем.

Blair Conrad 16.11.2008 22:49

Для односвязного списка и указателя p в список вы можете вставить только после p, но не перед ним.

Douglas Leeder 17.11.2008 00:12

Обратите внимание, что это внешний список, а не навязчивый.

Steve Jessop 17.11.2008 00:25

@ Дуглас Лидер - это не совсем так. На самом деле в этом вопросе есть уловка, которая делает это возможным.

Blair Conrad 17.11.2008 00:55

Чего вы не делаете, так это связывания элемента, который был до p до вставки y в y. Итак, пока y вставляется перед p, никто сейчас не указывает на y (по крайней мере, не в фрагменте кода, который вы показали).

Вы можете вставить в постоянное время, только если знаете позиции элементов, между которыми вам нужно вставить y. Если вам нужно искать эту позицию, вы никогда не сможете вставить постоянное время в один список ссылок.

когда я делаю tmp.element, я хочу изменить часть данных узла, но не указатель. Разве это не правильный способ сделать это? Есть ли в java такая вещь, как tmp.value?

101010110101 16.11.2008 22:31

Как насчет использования кода, который уже есть? LinkedHashMap, LinkedList, LinkedHashSet. Вы также можете проверить код и извлечь из него уроки.

create a node ptr
ptr->info = item //item is the element to be inserted...
ptr->next = NULL
if (start == NULL) //insertion at the end...
    start = ptr
else
    temp = ptr
    while (temp->next != NULL)
        temp = temp->next
    end while 
end if
if (start == NULL) //insertion at the beginning...
    start = ptr
else
    temp = start
    ptr->info = item
    ptr->next = start
    start = ptr
end if
temp = start //insertion at specified location...
for (i = 1; i < pos-1; i++)
    if (start == NULL)
        start = ptr
    else
        t = temp
        temp = temp->next
    end if
end for
t->next = ptr->next
t->next = ptr

Причина, по которой узел заголовка и хвоста задается в вопросе, заключается в обновлении ссылки заголовка и хвоста, если создаваемый вами замещающий узел становится заголовком или хвостом. Другими словами, данный предыдущий узел является либо заголовком, либо хвостом.

В отдельном LinkedList только добавление узла в начало списка или создание списка только с одним узлом потребует O (1). ИЛИ, поскольку они предоставили TailNode, также для вставки узла в конец списка потребуется O (1).

каждая другая операция вставки займет O (n).

Другие вопросы по теме