🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.c
Article #308447

kiedy używać listy, a kiedy wektora?

#308447
From: M.M.
Date: Mon, 18 Apr 2016 15:41
58 lines
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-mail

Show 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