Article View: pl.comp.lang.c
Article #308447kiedy używać listy, a kiedy wektora?
From: M.M.
Date: Mon, 18 Apr 2016 15:41
Date: Mon, 18 Apr 2016 15:41
58 lines
3902 bytes
3902 bytes
Kiedyś myślałem, że odpowiedź na pytanie w tytule jest prosta...
Główną wadą wektora jest to, że usuwanie elementu zachodzi w
pesymistycznym czasie N, a nawet w średnim 0.5*N. Niby wniosek
jest oczywisty: jeśli zajdzie konieczność usuwania elementów ze
środka wektora, to wszelkie prawdziwe lub potencjalne zalety
wektora zostaną pochłonięte przez straty z powolnego usuwania,
więc należy użyć listy.
Ale ale ale...
Przecież można se na kolanie napisać (albo znaleźć gotowy)
wektor który zamiast typu T, przechowuje strukturę Item:
template<class T>
struct Item {
int next;
T t;
};
Pole next to następny wolne element lub wartość -1 gdy element
przechowuje dane. Czyli pole next pełni rolę listy wolnych elementów.
Dodawanie jest tak samo szybkie jak do wektora, a nawet szybsze, bo
nie alokujemy, tylko kopiujemy na wcześniej prealokowane pozycje.
Usuwanie jest bardzo szybkie, tylko wpisujemy w next następną
wolną pozycję a usuwaną zapamiętujemy jako głowę listy. Przeiterowanie
takiego wektora będzie też szybsze niż przeiterowanie listy, oczywiście
pod warunkiem, że nie usuniemy więcej niż kilka procent elementów.
Więc odpowiedź na pytanie w tytule już się robi trudna, bo zależy od
tego, ile dodamy elementów maksymalnie, ile średnio usuniemy i jak
często będziemy iterować po całości. A to dopiero rozgrzewka. Dlaczego
to dopiero rozgrzewa?
A no dlatego, że w wektorze można usuwać poprzez zastąpienie elementu
usuwanego elementem ostatnim. Rozwiązanie takie ma wadę: będzie trzeba
zmienić wszystkie odwołania w całym programie do ostatniego elementu.
Na tym nie koniec. Można zadeklarować zbiór usuniętych elementów. Zbiór
oparty o hash-table szybko testuje, czy wpis spod indexu x jest wolny
czy zajęty, jednak w trakcie iterowania trzeba wykonać N testów - mimo
wszystko może to być wolne.
Można zamiast hash-table użyć drzewa do zapamiętania zwolnionych pozycji.
Szukamy pierwszej pozycji wolnej w drzewku i iterujemy po elementach
zajętych aż do napotkania wcześniej znalezionej pozycji wolnej. Potem
szukamy następnej pozycji wolnej. Czyli test w drzewie będzie
wykonany tylko tyle razy, ile zostało zwolnionych elementów - wydaje
się to bardzo szybkim rozwiązaniem.
To ostatnie rozwiązanie wydaje się bardzo dobre dla wektorów z
których usuwa się czasami mały odsetek elementów. Rozwiązanie na
drzewie (chodzi oczywiście o drzewo poszukiwań binarnych) będzie
wymagało mało testów i będzie miało mały narzut pamięciowy.
Co myślicie o tym wszystkim?
Pozdrawiam
Technical Details
Message-ID:
<117f9b9b-d150-440d-bee6-60eab4b1f360@googlegroups.com>Path:
mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!newsfeed.pionier.net.pl!feeder.erje.net!2.eu.feeder.erje.net!usenet.blueworldhosting.com!feeder01.blueworldhosting.com!border2.nntp.dca1.giganews.com!nntp.giganews.com!7no4327002qgj.0!news-out.google.com!u9ni315igk.0!nntp.google.com!gy3no5780638igb.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mailShow Full Headers
Complete Article Headers
X-Received: by 10.140.92.48 with SMTP id a45mr23882301qge.14.1460994102365; Mon, 18 Apr 2016 08:41:42 -0700 (PDT) X-Received: by 10.50.129.97 with SMTP id nv1mr321929igb.7.1460994102326; Mon, 18 Apr 2016 08:41:42 -0700 (PDT) Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!newsfeed.pionier.net.pl!feeder.erje.net!2.eu.feeder.erje.net!usenet.blueworldhosting.com!feeder01.blueworldhosting.com!border2.nntp.dca1.giganews.com!nntp.giganews.com!7no4327002qgj.0!news-out.google.com!u9ni315igk.0!nntp.google.com!gy3no5780638igb.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: pl.comp.lang.c Date: Mon, 18 Apr 2016 08:41:41 -0700 (PDT) Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=178.37.232.66; posting-account=xjvq9QoAAAATMPC2X3btlHd_LkaJo_rj NNTP-Posting-Host: 178.37.232.66 User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <117f9b9b-d150-440d-bee6-60eab4b1f360@googlegroups.com> Subject: kiedy używać listy, a kiedy wektora? From: "M.M." <mmarszik@gmail.com> Injection-Date: Mon, 18 Apr 2016 15:41:42 +0000 Lines: 67 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit