как применить двоичный поиск O (log n) в отсортированном связанном списке?

недавно я наткнулся на один интересный вопрос в связанном списке. Сортируется по одному связанному списку, и мы должны найти один элемент из этого списка.

сложность времени не должна превышать O(log n). Похоже, что нам нужно применить двоичный поиск в этом связанном списке. Как? Поскольку связанный список не обеспечивает случайный доступ, если мы попытаемся применить алгоритм двоичного поиска, он достигнет O (n), поскольку нам нужно найти длину списка и перейти к середине.

какие идеи?

6 ответов


это, конечно, невозможно с простым односвязанным списком.

Sketch proof: чтобы изучить последний узел односвязного списка, мы должны выполнить n-1 операции следования указателю "next" [доказательство индукцией о том, что существует только одна ссылка на k+1- й узел, и он находится в kth узел, и требуется операция, чтобы следовать за ним]. Для некоторых входов необходимо изучить последний узел (в частности, если искомый элемент равен или больше, чем его значение). Следовательно, для некоторых входов требуемое время пропорционально n.

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

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



в связанном списке двоичный поиск может не достигать сложности O (log n), но, по крайней мере, может быть немного достигнут с помощью метода двойного указателя, как описано здесь в этой исследовательской работе:http://www.ijcsit.com/docs/Volume%205/vol5issue02/ijcsit20140502215.pdf


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

очевидно, что это только ответ на трюк вопрос вариант этой проблемы, но проблема всегда невозможность или трюк вопрос.


Да, это возможно на языке java, как показано ниже..

Collections.<T>binarySearch(List<T> list, T key)

для бинарного поиска на любом List. Он работает на ArrayList и LinkedList и на любой другой List.


используйте карты для создания списков ссылок.
Карта M, M[первый элемент]=второй элемент, M[второй элемент]=третий элемент ,
...
...
это связанный список...
но потому что это карта...
который внутренне использует двоичный поиск для поиска любого элемента..
любой поиск элементов займет O (log n)