Skip to content

Latest commit

 

History

History
11 lines (6 loc) · 3.47 KB

LinearStringSorting.md

File metadata and controls

11 lines (6 loc) · 3.47 KB

Сортиране на списък от стрингове в линейно време и с линейна допълн. памет

Нека имаме n на брой думи с обща дължина m. Под линейно време ще разбираме O(m). Това е общата големина на входа, за която обаче няма строго съответствие с броя елементи - разлика с масивите с числа, например - заради което двете големини се разглеждат поотделно.

Нека създадем празен Trie (чете се "трай") и вмъкнем всяка дума от списъка в него. Заради особеността на тази структура вмъкването на дума в нея отнема време и памет, линейни по големината на тази дума, без значение от броя вече съдържани други думи (!) => вмъкването на всички ще отнеме общо O(m) време и допълнителна памет. Б.о.о. можем да допуснем, че възлите в това дърво пазят наследниците си подредени - например с масив от указатели, в който първият съответства на буквичката 'a', вторият на 'b' и т.н. Аналогът на обхождане корен-ляво-дясно в такова дърво първо би посетило наследника с 'a' (ако съществува), после с 'b' и т.н. преди да се върне нагоре по рекурсивните извиквания. Това обхождане би отнело също O(m) време и памет и с него ще получим думите от първоначалния списък в лексикографска наредба, за общо време и допълнителна памет O(m) - линейни по големината на входа.

Как се използва за числа - можем да си представяме неотрицателните* числа като "думи" от битове, всяка с дължина lgn бита. Тогава m = nlgn и получаваме отново O(nlgn) алгоритъм за сортиране на числа, въпреки че не използва директни сравнения.

Заб.: алгоритъмът има голяма теоретична полза, както и връзка с много други алгоритми и структури от данни за стрингове. На практика обаче е неефективен заради огромното количество допълнителна памет (възлите в дървото са O(n), но заемат по много памет), както и относително бавното траверсиране на дървото (hint: cache/memory locality)

*Ако имаме отрицателни числа, то можем предварително да "изместим" всяко число в списъка така, че да станат неотрицателни, и да ги възстановим след сортирането.