Днес в училище учителят ни помоли да приложим алгоритъм за изтриване на дубликати. Не е толкова трудно и всички измислиха следното решение (псевдокод):
for i from 1 to n - 1
for j from i + 1 to n
if v[i] == v[j] then remove(v, v[j]) // remove(from, what)
next j
next i
Изчислителната сложност за този алго е n(n-1)/2
. (Ние сме в гимназията и не сме говорили за big-O, но изглежда е O(n^2)
). Това решение изглежда грозно и, разбира се, бавно, затова се опитах да кодирам нещо по-бързо:
procedure binarySearch(vector, element, *position)
// this procedure searches for element in vector, returning
// true if found, false otherwise. *position will contain the
// element's place (where it is or where it should be)
end procedure
----
// same type as v
vS = new array[n]
for i from 1 to n - 1
if binarySearch(vS, v[i], &p) = true then
remove(v, v[i])
else
add(vS, v[i], p) // adds v[i] in position p of array vS
end if
next i
По този начин vS
ще съдържа всички елементи, които вече сме преминали. Ако елемент v[i]
е в този масив, тогава той е дубликат и се премахва. Изчислителната сложност за двоичното търсене е log(n)
, а за основния цикъл (втори фрагмент) е n
. Следователно целият CC е n*log(n)
, ако не греша.
След това имах друга идея за използване на двоично дърво, но не мога да я запиша.
По принцип въпросите ми са:
- Правилно ли е изчислението ми на CC? (и ако не, защо?)
- Има ли по-бърз метод за това?
Благодаря
vS
и какво точно правиadd
? - person Robin Green   schedule 20.05.2011