Download - 05. SPA1 - Dvostruko Povezane Liste
DVOSTRUKO POVEZANE
LISTE
Strukture podataka i algoritmi 1
Dvostruko povezane liste (1)
Dvostruko povezana lista - DPL (doubly-linked list - DLL) se sastoji od sekvence čvorova koji su povezani vezama u oba smera.
Svaki čvor DPL sadrži element liste i veze ka čvoru prethodniku i čvoru sledbeniku (ili null veze).
Zaglavlje DPL sadrži veze ka prvom i ka poslednjem čvoru (ili null veze ako je lista prazna).
pig dog rat cat
dog
Dvostruko povezane liste (2)
Java klasa koja implementira čvor DPL: public class DLLNode {
protected Object element;
protected DLLNode pred, succ;
public DLLNode (Object elem,
DLLNode pred, DLLNode succ) {
this.element = elem;
this.pred = pred;
this.succ = succ;
}
}
Dvostruko povezane liste (3)
Java klasa koja impementira zaglavlje
DPL: public class DLL {
private DLLNode first, last;
public DLL () {
// Construct an empty DLL.
this.first = null;
this.last = null;
}
…
}
DLL methods (to follow)
ant bat cat first
last
Prolazak kroz DPL (1)
Metod u klasi DLL koji ispisuje elemente liste od
poslednjeg do prvog:
public void printLastToFirst () {
// Stampa sve elemente od poslednjeg do prvog. for (DLLNode curr = this.last;
curr != null; curr = curr.pred)
System.out.println(curr.element);
}
Demonstracija:
curr
ant bat cat first
last
curr
ant bat cat first
last
curr
ant bat cat first
last
curr
ant bat cat first
last
Prolazak kroz DPL (2)
Metod u klasi DLL koji ispisuje elemente liste
od prvog do poslednjeg:
public void printFirstToLast () {
// Stampa sve elemente od prvog do poslednjeg.
for (DLLNode curr = this.first;
curr != null; curr = curr.succ)
System.out.println(curr.element);
}
Operacije sa DPL (1)
Metod u klasi DLL koji briše prvi čvor: public void deleteFirst () {
// Brise prvi element liste.
if (this.first != null)
if (this.first.succ != null) {
DLLNode second = this.first.succ;
second.pred = null;
this.first = second;
} else {
this.first = null;
this.last = null;
}
}
Demonstracija:
ant bat cat first
last
second
ant bat cat first
last
second
ant bat cat first
last
second
ant bat cat first
last
Operacije sa DPL (2)
Metod u klasi DLL koji briše poslednji čvor: public void deleteLast () {
// Brise poslednji element.
if (this.last != null)
if (this.last.pred != null){
DLLNode penult = this.last.pred;
penult.succ = null;
this.last = penult;
} else {
this.first = null;
this.last = null;
}
}
Demonstracija:
ant bat cat first
last
penult
ant bat cat first
last
penult
ant bat cat first
last
penult
ant bat cat first
last
DPL = unapred i unazad povezana JPL
ant bat cat DPL:
ant bat cat Unapred
JPL:
ant bat cat Unazad
JPL:
Ubacivanje
Problem: Ubaciti novi element na proizvoljnu poziciju u
listi.
4 slučaja:
1) Ubacivanje u praznu listu;
2) Ubacivanje pre prvog elementa neprazne liste;
3) Ubacivanje posle poslednjeg elementa neprazne liste;
4) Ubacivanje između čvorova neprazne liste.
Algoritmu za ubacivanje je porteban pokazivač na
prethodnika/sledbenika novog čvora.
11
Ubacivanje u DPL (1)
Algoritam: Ubacujemo novi čvor elem na određenu poziciju u DPL
listi (spoljašnji pokazivači su first, last):
1. Neka je ins pokazivač na novokreirani čvor sa elementom elem, pokazivači na prethodni i na sledeći element su inicijalno null. 2. Ubaciti ins na željeno mesto u unapred povezanoj JPL koja počinje sa first. 3. Neka je pomoćni pokazivač succ sukcesor od ins’s u unapred povezanoj JPL (ili null ako ins nema sledbenika). 4. Ubaciti ins posle čvora na koji pokazuje succ u unazad povezanoj JPL koja počinje sa last. 5. Kraj.
Ubacivanje u DPL (2)
Pomoćni algoritam za ubacivanje u unapred povezanu JPL:
Ubaciti elem na datu poziciju u unapred povezanoj JPL koja počinje sa first:
1. Ako je potrebno ubaciti novi čvor na početak ili u praznu listu: 1.1. Postaviti vezu sledećeg od ins na first. 1.2. Postaviti first na ins. 2. Ako je potrebno ubaciti novi čvor iza čvora na koji pokazuje pred: 2.1. Postaviti vezu sledećeg od ins na vezu sledećeg od pred. 2.2. Postaviti vezu sledećeg od pred na ins. 3. Kraj.
Ubacivanje u DPL (3)
Pomoćni algoritam za ubacivanje u unazad povezanu JPL:
Ubaciti elem posle čvora succ u unazad povezanoj JPL koja počinje sa last:
1. Ako je potrebno ubaciti novi čvor na početak ili u praznu listu: 1.1. Postaviti vezu prethodnog od ins na last. 1.2. Postaviti last na ins. 2. Ako je potrebno ubaciti novi čvor iza čvora na koji pokazuje succ: 2.1. Postaviti vezu prethodnog od ins na vezu prethodnog od succ. 2.2. Postaviti vezu prethodnog od succ na ins. 3. Kraj.
Ubacivanje u DPL (4)
Demostracija (ubacivanje pre prvog čvora):
To insert elem at a given point in the DLL headed by (first, last):
1. Make ins a link to a newly-created node with element elem,
predecessor null, and successor null.
2. Insert ins at the insertion point in the forward SLL headed by first.
3. Let succ be ins’s successor (or null if ins has no successor).
4. Insert ins after node succ in the backward SLL headed by last.
5. Terminate.
bat cat first
last
To insert elem at a given point in the DLL headed by (first, last):
1. Make ins a link to a newly-created node with element elem,
predecessor null, and successor null.
2. Insert ins at the insertion point in the forward SLL headed by first.
3. Let succ be ins’s successor (or null if ins has no successor).
4. Insert ins after node succ in the backward SLL headed by last.
5. Terminate.
ins ant
bat cat first
last
To insert elem at a given point in the DLL headed by (first, last):
1. Make ins a link to a newly-created node with element elem,
predecessor null, and successor null.
2. Insert ins at the insertion point in the forward SLL headed by first.
3. Let succ be ins’s successor (or null if ins has no successor).
4. Insert ins after node succ in the backward SLL headed by last.
5. Terminate.
ins ant
bat cat first
last
To insert elem at a given point in the DLL headed by (first, last):
1. Make ins a link to a newly-created node with element elem,
predecessor null, and successor null.
2. Insert ins at the insertion point in the forward SLL headed by first.
3. Let succ be ins’s successor (or null if ins has no successor).
4. Insert ins after node succ in the backward SLL headed by last.
5. Terminate.
ins ant
bat cat first
last
succ
To insert elem at a given point in the DLL headed by (first, last):
1. Make ins a link to a newly-created node with element elem,
predecessor null, and successor null.
2. Insert ins at the insertion point in the forward SLL headed by first.
3. Let succ be ins’s successor (or null if ins has no successor).
4. Insert ins after node succ in the backward SLL headed by last.
5. Terminate.
ins ant
bat cat first
last
succ
To insert elem at a given point in the DLL headed by (first, last):
1. Make ins a link to a newly-created node with element elem,
predecessor null, and successor null.
2. Insert ins at the insertion point in the forward SLL headed by first.
3. Let succ be ins’s successor (or null if ins has no successor).
4. Insert ins after node succ in the backward SLL headed by last.
5. Terminate.
ant
bat cat first
last
Ubacivanje u DPL (5)
Demonstracija (ubacivanje posle poslednjeg čvora):
To insert elem at a given point in the DLL headed by (first, last):
1. Make ins a link to a newly-created node with element elem,
predecessor null, and successor null.
2. Insert ins at the insertion point in the forward SLL headed by first.
3. Let succ be ins’s successor (or null if ins has no successor).
4. Insert ins after node succ in the backward SLL headed by last.
5. Terminate.
bat cat first
last
To insert elem at a given point in the DLL headed by (first, last):
1. Make ins a link to a newly-created node with element elem,
predecessor null, and successor null.
2. Insert ins at the insertion point in the forward SLL headed by first.
3. Let succ be ins’s successor (or null if ins has no successor).
4. Insert ins after node succ in the backward SLL headed by last.
5. Terminate.
ins dog
bat cat first
last
To insert elem at a given point in the DLL headed by (first, last):
1. Make ins a link to a newly-created node with element elem,
predecessor null, and successor null.
2. Insert ins at the insertion point in the forward SLL headed by first.
3. Let succ be ins’s successor (or null if ins has no successor).
4. Insert ins after node succ in the backward SLL headed by last.
5. Terminate.
ins dog
bat cat first
last
To insert elem at a given point in the DLL headed by (first, last):
1. Make ins a link to a newly-created node with element elem,
predecessor null, and successor null.
2. Insert ins at the insertion point in the forward SLL headed by first.
3. Let succ be ins’s successor (or null if ins has no successor).
4. Insert ins after node succ in the backward SLL headed by last.
5. Terminate.
ins dog
bat cat first
last
succ
To insert elem at a given point in the DLL headed by (first, last):
1. Make ins a link to a newly-created node with element elem,
predecessor null, and successor null.
2. Insert ins at the insertion point in the forward SLL headed by first.
3. Let succ be ins’s successor (or null if ins has no successor).
4. Insert ins after node succ in the backward SLL headed by last.
5. Terminate.
ins dog
bat cat first
last
succ
To insert elem at a given point in the DLL headed by (first, last):
1. Make ins a link to a newly-created node with element elem,
predecessor null, and successor null.
2. Insert ins at the insertion point in the forward SLL headed by first.
3. Let succ be ins’s successor (or null if ins has no successor).
4. Insert ins after node succ in the backward SLL headed by last.
5. Terminate.
dog
bat cat first
last
To insert elem at a given point in the DLL headed by (first, last):
1. Make ins a link to a newly-created node with element elem,
predecessor null, and successor null.
2. Insert ins at the insertion point in the forward SLL headed by first.
3. Let succ be ins’s successor (or null if ins has no successor).
4. Insert ins after node succ in the backward SLL headed by last.
5. Terminate.
fox dog first
last
To insert elem at a given point in the DLL headed by (first, last):
1. Make ins a link to a newly-created node with element elem,
predecessor null, and successor null.
2. Insert ins at the insertion point in the forward SLL headed by first.
3. Let succ be ins’s successor (or null if ins has no successor).
4. Insert ins after node succ in the backward SLL headed by last.
5. Terminate.
ins
fox dog
eel
first
last
To insert elem at a given point in the DLL headed by (first, last):
1. Make ins a link to a newly-created node with element elem,
predecessor null, and successor null.
2. Insert ins at the insertion point in the forward SLL headed by first.
3. Let succ be ins’s successor (or null if ins has no successor).
4. Insert ins after node succ in the backward SLL headed by last.
5. Terminate.
ins
fox dog
eel
first
last
Ubacivanje u DPL (6)
Demonstracija (ubacivanje u sredinu liste):
To insert elem at a given point in the DLL headed by (first, last):
1. Make ins a link to a newly-created node with element elem,
predecessor null, and successor null.
2. Insert ins at the insertion point in the forward SLL headed by first.
3. Let succ be ins’s successor (or null if ins has no successor).
4. Insert ins after node succ in the backward SLL headed by last.
5. Terminate.
ins
fox dog
eel
first
last
succ
To insert elem at a given point in the DLL headed by (first, last):
1. Make ins a link to a newly-created node with element elem,
predecessor null, and successor null.
2. Insert ins at the insertion point in the forward SLL headed by first.
3. Let succ be ins’s successor (or null if ins has no successor).
4. Insert ins after node succ in the backward SLL headed by last.
5. Terminate.
ins
fox dog
eel
first
last
succ
To insert elem at a given point in the DLL headed by (first, last):
1. Make ins a link to a newly-created node with element elem,
predecessor null, and successor null.
2. Insert ins at the insertion point in the forward SLL headed by first.
3. Let succ be ins’s successor (or null if ins has no successor).
4. Insert ins after node succ in the backward SLL headed by last.
5. Terminate.
fox dog
eel
first
last
Ubacivanje u DPL - metod (1)
public void insert (Object elem, DLLNode pred) {
// Ubacuje elem na datu poziciju u DPL posle cvora
// pred, ili pre prvog cvora ako je pred null.
DLLNode ins = new DLLNode(elem, null, null);
if (pred == null) {
// ubacivanje na pocetak
ins.succ = this.first;
this.first = ins;
if (this.last == null)
// ubacivanje u praznu listu
this.last = ins;
else
this.first.succ.pred = ins;
...
Ubacivanje u DPL - metod (2)
...
} else {
ins.succ = pred.succ;
pred.succ = ins;
if (ins.succ == null){
// ubacivanje na kraj
ins.pred = this.last;
this.last = ins;
} else {
ins.pred = ins.succ.pred;
ins.succ.pred = ins;
}
}
}
Brisanje
Problem: Obrisati zadati čvor iz liste.
Četiri slučaja:
1) Brisanje jedinog čvora;
2) Brisanje prvog, ali ne i poslednjeg čvora;
3) Brisanje poslednjeg ali ne i prvog čvora;
4) Brisanje čvora u sredini.
Potrebno je da algoritam ima pokazivač na čvor
koji brišemo.
Brisanje iz DPL (1)
Algoritam:
Brisati čvor na koji pokazuje del iz DPL (spoljašnji pokazivači su first, last):
1. Neka pred i succ pokazuju na čvorove prethodnika i sledbenika od čvora del. 2. Obrisati čvor del, čiji je prethodnik pred, iz unapred povezane JPL koja počinje sa first. 3. Obrisati čvor del, čiji je prethodnik succ, iz unazad povezane JLP koja počinje sa last. 4. Kraj.
To delete node del from the DLL headed by (first, last):
1. Let pred and succ be node del’s predecessor and successor.
2. Delete node del, whose predecessor is pred, from the forward
SLL headed by first.
3. Delete node del, whose successor is succ, from the backward SLL
headed by last.
4. Terminate.
ant bat cat first
last
del
To delete node del from the DLL headed by (first, last):
1. Let pred and succ be node del’s predecessor and successor.
2. Delete node del, whose predecessor is pred, from the forward
SLL headed by first.
3. Delete node del, whose successor is succ, from the backward SLL
headed by last.
4. Terminate.
pred
ant bat cat first
last
succ
del
Brisanje iz DPL (2)
Demonstracija (brisanje prvog ali ne i poslednjeg
čvora):
To delete node del from the DLL headed by (first, last):
1. Let pred and succ be node del’s predecessor and successor.
2. Delete node del, whose predecessor is pred, from the forward
SLL headed by first.
3. Delete node del, whose successor is succ, from the backward SLL
headed by last.
4. Terminate.
pred
ant bat cat first
last
succ
del
To delete node del from the DLL headed by (first, last):
1. Let pred and succ be node del’s predecessor and successor.
2. Delete node del, whose predecessor is pred, from the forward
SLL headed by first.
3. Delete node del, whose successor is succ, from the backward SLL
headed by last.
4. Terminate.
pred
ant bat cat first
last
succ
del
To delete node del from the DLL headed by (first, last):
1. Let pred and succ be node del’s predecessor and successor.
2. Delete node del, whose predecessor is pred, from the forward
SLL headed by first.
3. Delete node del, whose successor is succ, from the backward SLL
headed by last.
4. Terminate.
ant bat cat first
last
Brisanje iz DPL (3)
Demonstracija (brisanje unutrašnjeg čvora):
To delete node del from the DLL headed by (first, last):
1. Let pred and succ be node del’s predecessor and successor.
2. Delete node del, whose predecessor is pred, from the forward
SLL headed by first.
3. Delete node del, whose successor is succ, from the backward SLL
headed by last.
4. Terminate.
del
fox dog eel first
last
To delete node del from the DLL headed by (first, last):
1. Let pred and succ be node del’s predecessor and successor.
2. Delete node del, whose predecessor is pred, from the forward
SLL headed by first.
3. Delete node del, whose successor is succ, from the backward SLL
headed by last.
4. Terminate.
del
fox dog eel first
last
pred succ
To delete node del from the DLL headed by (first, last):
1. Let pred and succ be node del’s predecessor and successor.
2. Delete node del, whose predecessor is pred, from the forward
SLL headed by first.
3. Delete node del, whose successor is succ, from the backward SLL
headed by last.
4. Terminate.
del
fox dog eel first
last
pred succ
To delete node del from the DLL headed by (first, last):
1. Let pred and succ be node del’s predecessor and successor.
2. Delete node del, whose predecessor is pred, from the forward
SLL headed by first.
3. Delete node del, whose successor is succ, from the backward SLL
headed by last.
4. Terminate.
del
fox dog eel first
last
pred succ
To delete node del from the DLL headed by (first, last):
1. Let pred and succ be node del’s predecessor and successor.
2. Delete node del, whose predecessor is pred, from the forward
SLL headed by first.
3. Delete node del, whose successor is succ, from the backward SLL
headed by last.
4. Terminate.
fox dog eel first
last
Brisanje iz DPL – metod (1)
public void delete (DLLNode del) {
if (del.pred == null && del.succ == null) {
// brisemo jedini element
this.first = null;
this.last = null;
} else if (del.pred == null) {
// brisemo prvi
del.succ.pred = null;
this.first = del.succ;
...
Brisanje iz DPL – metod (2)
...
} else if (del.succ == null) {
// brisemo poslednji
del.pred.succ = null;
this.last = del.pred;
} else {
// brisemo unutrasnji
del.pred.succ = del.succ;
del.succ.pred = del.pred;
}
}
Poređenje algoritama za ubacivanje
i izbacivanje
Algoritam JPL DPL
Ubacivanje O(1) O(1)
Brisanje O(n) O(1)