Массив против связанного списка - PullRequest
187 голосов
/ 03 октября 2008

Зачем кому-то использовать связанный список над массивом?

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

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

Этот вопрос не является дубликатом этого вопроса , поскольку другой вопрос касается конкретно определенного класса Java, в то время как этот вопрос касается общих структур данных.

Ответы [ 33 ]

3 голосов
/ 30 августа 2013

Связанный список

Это более предпочтительно, когда дело доходит до вставки! В основном, это то, что он имеет дело с указателем

1 -> 3 -> 4

Вставка (2)

1 ........ 3 ...... 4
..... 2

Наконец

1 -> 2 -> 3 -> 4

Одна стрелка из 2 точек на 3 и стрелка 1 точки на 2

Simple!

Но из массива

| 1 | 3 | 4 |

Вставка (2) | 1 | 3 | | 4 | | 1 | | 3 | 4 | | 1 | 2 | 3 | 4 |

Ну, любой может представить разницу! Просто для 4 индекса мы выполняем 3 шага

Что если длина массива равна миллиону? Эффективен ли массив? Ответ - нет! :)

То же самое относится и к удалению! В связанном списке мы можем просто использовать указатель и обнулить элемент и следующий в классе объекта! Но для массива нам нужно выполнить shiftLeft ()

Надеюсь, это поможет! :)

3 голосов
/ 29 августа 2010

В массиве вы имеете право доступа к любому элементу за O (1) раз. Таким образом, он подходит для таких операций, как Бинарный поиск, Быстрая сортировка и т. Д. Связанный список, с другой стороны, подходит для удаления вставки, как и в O (1) раз. Оба имеют как преимущества, так и недостатки, и предпочтение одного из них сводится к тому, что вы хотите реализовать.

- Большой вопрос, можем ли мы иметь гибрид обоих. Что-то вроде того, что Python и Perl реализуют в виде списков.

3 голосов
/ 26 июля 2010

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

Во-первых, мы должны отметить, что если вы хотите сохранить ссылки на объекты вне самого набора, вы, скорее всего, в конечном итоге будете хранить указатели в массиве, а не сами объекты. В противном случае вы не сможете вставить в массив - если объекты встроены в массив, они будут перемещаться во время вставки, и любые указатели на них станут недействительными. То же самое верно для индексов массива.

Ваша первая проблема, как вы сами отметили, заключается в том, что связанный с вставкой список позволяет вставлять в O (1), но массив обычно требует O (n). Эта проблема может быть частично преодолена - можно создать структуру данных, которая предоставляет массивоподобный обычный порядок доступа, где чтение и запись в худшем случае являются логарифмическими.

Ваша вторая и более серьезная проблема заключается в том, что заданным элементом для нахождения следующего элемента является O (n). Если набор не был изменен, вы могли бы сохранить индекс элемента в качестве ссылки вместо указателя, таким образом делая find-next операцией O (1), но, как и все, что у вас есть, это указатель на сам объект и никак определить его текущий индекс в массиве, кроме как путем сканирования всего «массива». Это непреодолимая проблема для массивов - даже если вы можете оптимизировать вставки, вы ничего не можете сделать для оптимизации операции поиска следующего типа.

3 голосов
/ 30 августа 2009

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

2 голосов
/ 03 октября 2008

Единственная причина для использования связанного списка заключается в том, что вставить элемент легко (также удалить).

Разочарование может быть в том, что указатели занимают много места.

А с этим кодированием сложнее: Обычно вам не нужен список связанных кодов (или только один раз), они включены в СТЛ и это не так сложно, если вам все еще придется это делать.

1 голос
/ 12 мая 2019

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

1 голос
/ 07 декабря 2017

Почему кто-то хочет использовать связанный список над массивом?

Это только одна причина - если вам нужна структура данных связанного списка и используемый вами язык программирования не поддерживает указатели.

1 голос
/ 28 сентября 2016

В то время как многие из вас касались основных нативов / списков связанных списков и массивов, большинство сравнений показывают, насколько одно лучше / хуже другого. Например. Вы можете сделать произвольный доступ в массиве, но не возможно в связанном списке и других. Однако это предполагает, что списки ссылок и массив будут применены в аналогичном приложении. Однако правильный ответ должен заключаться в том, каким образом список ссылок будет предпочтительнее массива и наоборот в конкретном развертывании приложения. Предположим, вы хотите реализовать приложение-словарь, что бы вы использовали? Массив: ммм, он позволил бы легко получить доступ через бинарный поиск и другой алгоритм поиска ... но давайте подумаем, как список ссылок может быть лучше ... Скажем, вы хотите искать "Blob" в словаре. Имеет ли смысл иметь список ссылок A-> B-> C-> D ----> Z, а затем каждый элемент списка, также указывающий на массив или другой список всех слов, начинающихся с этой буквы ..

A -> B -> C -> ...Z
|    |    |
|    |    [Cat, Cave]
|    [Banana, Blob]
[Adam, Apple]

Теперь вышеприведенный подход лучше или плоский набор [Адам, Apple, Банан, Blob, Cat, Cave]? Будет ли это возможно с массивом? Таким образом, главное преимущество списка ссылок заключается в том, что вы можете иметь элемент, указывающий не только на следующий элемент, но также на какой-либо другой список ссылок / массив / кучу / или любую другую область памяти. Массив - это единая плоская непрерывная память, разделенная на блоки размером элемента, который он будет хранить. С другой стороны, список ссылок - это куски не непрерывных блоков памяти (могут быть любого размера и могут хранить что угодно), указывающие на каждую иначе, как вы хотите. Точно так же скажем, что вы делаете USB-накопитель. Теперь вы хотите, чтобы файлы были сохранены в виде любого массива или в виде списка ссылок? Я думаю, вы поняли, на что я указываю:)

1 голос
/ 10 июля 2015

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

Но, может быть, нам не нужно жить с ограничениями обоих и одновременно получать лучшее от обоих ... а?

Для удаления массива вы можете использовать байт 'Deleted', чтобы представить факт удаления строки, поэтому перестановка массива больше не требуется. Чтобы облегчить бремя вставок или быстро меняющихся данных, используйте для этого связанный список. Затем, обращаясь к ним, попросите свою логику сначала найти один, а затем другой. Таким образом, использование их в комбинации дает вам лучшее из обоих.

Если у вас действительно большой массив, вы можете объединить его с другим, гораздо меньшим массивом или связанным списком, где меньший содержит 20, 50, 100 последних использованных элементов. Если нужного вам нет в более коротком связанном списке или массиве, вы переходите к большому массиву. Если он найден там, вы можете добавить его в меньший связанный список / массив, исходя из предположения, что «последние использованные вещи больше всего подходят для повторного использования» (и, да, возможно, удаляют наименее недавно использованный элемент из списка). Это верно во многих случаях и решило проблему, которую мне пришлось решать в модуле проверки разрешений безопасности .ASP, с легкостью, элегантностью и впечатляющей скоростью.

1 голос
/ 20 июня 2012

В зависимости от вашего языка, некоторые из этих недостатков и преимуществ могут быть рассмотрены:

C Язык программирования : При использовании связанного списка (как правило, с помощью указателей структуры) необходимо убедиться, что у вас нет утечек памяти. Как упоминалось ранее, связанные списки легко перетасовать, потому что все, что делали, меняли указатели, но не забудем ли мы все освободить?

Java : Java имеет автоматический сборщик мусора, поэтому утечка памяти не будет проблемой, но скрытый от программиста высокого уровня - детали реализации того, что представляет собой связанный список. Такие методы, как удаление узла из середины списка, являются более сложной процедурой, чем некоторые пользователи языка ожидают.

...