Algoritma Dan Struktur Data: Linked List
Algoritma Dan Struktur Data: Linked List
STRUKTUR DATA
Linked List
Outline
¨ Linked Lists vs. Array
¨ Linked Lists dan Iterators
¨ Variasi Linked Lists:
¤ Doubly Linked Lists
¤ Circular Linked Lists
¤ Sorted Linked Lists
Tujuan
¨ Memahami struktur data linked-list
¨ Memahami kompleksitas dari operasi-operasi pada
ADT linked-list antara lain insert, delete, read
¨ Dapat mengimplementasikan linked-list
Apakah Linked List itu ?
CELL
Linked Lists
A0 A1 A2 A3
Ø Banyaknya anggota
§ Banyaknya elemen array ditentukan di awal & jumlahnya tetap
§ Elemen linked list dibuat di memori ketika dibutuhkan (ingat Alokasi
memory dinamis). Jumlahnya dinamis, dapat bertambah dan
berkurang sesuai keperluan
Akses harus dilakukan satu persatu, urut mulai dari sel terdepan
Cara menampilkan isi sel tertentu
header 37 38 40 52
37 4 38 2 40 13 52 40 NULL
Sel ke-1
pointer
pPre
After:
pNew 39
pHead
pPre
Menambahkan node ke awal list
Before:
pNew -> next = pHead; // set link to NULL
pNew 39
pHead = pNew;// point list to first node
pHead 75 124
pPre
After:
pNew 39
pHead
75 124
pPre
Menambahkan node di tengah list
Before
pNew -> next = pPre -> next;
pNew 64
pPre -> next = pNew;
55 124
pPre
After:
pNew 64
55 124
pPre
Ilustrasi Insertion
a b c d
current
a x b c d
current x
Langkah-langkah menyisipkan
Sisip efisien
Menambahkan node akhir list
Before:
pNew -> next = NULL;
pNew 144
pPre -> next = pNew;
55 124
pPre
After:
pNew 144
55 124
pPre
Menambahkan node pada linked list
Terdapat empat tahap untuk menambah node linked list:
¨ Membuat node baru.
¨ Mendapatkan node yang terletak sebelum node baru disisipkan (pPre)
¨ Atur next node baru agar menunjuk node sesudah posisi penyisipan.
¨ Atur next pPre agar menunjuk node baru.
Menghapus node dari linked list
Before: Code:
pHead 75 124 pHead = pCur -> next;
free(pCur);
pPre pCur
After:
pHead Recycled 124
pPre pCur
Langkah menghapus elemen di tengah
¨ Proses menghapus dilakukan dengan mengabaikan
elemen yang hendak dihapus dengan cara melewati
pointer (reference) dari elemen tersebut langsung
pada elemen selanjutnya.
¨ Elemen x dihapus dengan meng-assign field next
pada elemen a dengan alamat b.
a x b
current
a b
current
Langkah-langkah menghapus elemen
di tengah
¨ Butuh menyimpan alamat node yang terletak
sebelum node yang akan dihapus. (pada gambar
node current, berisi elemen a)
current.next = current.next.next;
a x b
current
a x b
current
Before:
pPre -> next = pour -> next;
75 96 124 free(pCur);
pPre pCur
After:
Recycled
75 124
pPre pCur
Traversing a Linked List
¨ mengunjungi semua node yang ada pada list dari head sampai node
terakhir
Header Node
¨ Menghapus dan menambahkan elemen pertama menjadi kasus
khusus.
¨ Dapat dihindari dengan menggunakan header node;
n Tidak berisikan data, digunakan untuk menjamin bahwa
selalu ada elemen sebelum elemen pertama yang sebenarnya
pada linked list.
n Elemen pertama diperoleh dengan:
current=header.next;
n Empty list jika: header.next == null;
¨ Proses pencarian dan pembacaan mengabaikan header node.
List Interface
List Implementation
List Implementation
Iterator Class
¨ Untuk melakukan sebagian besar operasi-operasi
pada List, kita perlu menyimpan informasi posisi saat
ini. (current position).
¨ Kelas List menyediakan method yang tidak bergantung
pada posisi. Method tersebut antara lain: isEmpty,
dan makeEmpty.
¨ List iterator (ListItr) menyediakan method-method
yang umum digunakan untuk melakukan operasi pada
list antara lain: advance, retrieve, first.
¨ Internal struktur dari List di encapsulasi oleh List
iterator.
¨ Informasi posisi current disimpan dalam object iterator.
Iterator Class
// Insert x after current position
void insert (x);
// Remove x
void remove (x);
// Remove item after current position
void removeNext( );
// Set current position to view x
boolean find( x );
// Set current position to prior to first
void zeroth ();
// Set current position to first
void first( );
// Set current to the next node
void advance ();
// True if at valid position in list
boolean isInList ();
// Return item in current position
Object retrieve()
/**
Construct the list.
As a result of the construction, the current position is
the first item, unless the list is empty, in which case
the current position is the zeroth item.
@param anyList a LinkedList object to which this iterator is
permanently bound.
*/
public LinkedListItr( LinkedList anyList )
{
theList = anyList;
current = theList.isEmpty( ) ? theList.header :
theList.header.next;
}
/**
Construct the list.
@param anyList a LinkedList object to which this iterator is
permanently bound. This constructor is provided for
convenience. If anyList is not a LinkedList object, a
ClassCastException will result.
*/
public LinkedListItr( List anyList ) throws ClassCastException{
this( ( LinkedList ) anyList );
}
/**
* Advance the current position to the next node in the list.
* If the current position is null, then do nothing.
* No exceptions are thrown by this routine because in the
* most common use (inside a for loop), this would require the
* programmer to add an unnecessary try/catch block.
*/
public void advance( ){
if( current != null )
current = current.next;
}
/**
* Return the item stored in the current position.
* @return the stored item or null if the current position
* is not in the list.
*/
public Object retrieve( ){
return isInList( ) ? current.element : null;
}
/**
* Set the current position to the header node.
*/
public void zeroth( ){
current = theList.header;
}
/**
* Set the current position to the first node in the list.
* This operation is valid for empty lists.
*/
public void first( ){
current = theList.header.next;
}
/**
* Insert after the current position.
* current is set to the inserted node on success.
* @param x the item to insert.
* @exception ItemNotFound if the current position is null.
*/
public void insert( Object x ) throws ItemNotFound
{
if( current == null )
throw new ItemNotFound( "Insertion error" );
current = itr;
return true;
}
/**
* Remove the first occurrence of an item.
* current is set to the first node on success;
* remains unchanged otherwise.
* @param x the item to remove.
* @exception ItemNotFound if the item is not found.
*/
public void remove( Object x ) throws ItemNotFound
{
ListNode itr = theList.header;
/**
* Test if the current position references a valid list item.
* @return true if the current position is not null and is
* not referencing the header node.
*/
public boolean isInList( )
{
return current != null && current != theList.header;
}
Exceptions
¨ Beberapa method dapat menthrow ItemNotFound exceptions.
¨ Namun, jangan menggunakan exceptions secara berlebihan karena
setiap exception harus di tangkap (caught) atau di teruskan
(propagate). Sehingga menuntut program harus selalu
membungkusnya dengan blok try/catch
¨ Contoh: method advance tidak men-throw exception, walaupun
sudah berada pada akhir elemen.
¨ Bayangkan bagaimana implementasi method listSize bila method
advance men-throw exception!
Linked List Properties
¨ Analisa Kompleksitas Running Time
¤ insert next, prepend - O(1)
¤ delete next, delete first - O(1)
¤ find - O(n)
¤ retrieve current position - O(1)
¨ Keuntungan
¤ Growable (bandingkan dengan array)
¤ Mudah (quick) dalam read/insert/delete elemen
pertama dan terakhir (jika kita juga menyimpan
referensi ke posisi terakhir, tidak hanya posisi
head/current)
¨ Kerugian
¤ Pemanggilan operator new untuk membuat node baru.
(bandingkan dengan array)
¤ Ada overhead satu reference untuk tiap node
Mencetak seluruh elemen Linked List
¨ Cara 1: Tanpa Iterator, loop
public class LinkedList {
class LinkedList {
public void print () {
if (header.next != null) {
header.next.print ();
}
}
}
Mencetak seluruh elemen Linked List(4)
¨ Cara 4: Menggunakan iterator
class LinkedList
{
...
public void print (List theList)
{
ListItr itr = new ListItr (theList);
}
Sorted Linked Lists
prev
A
next
head tail
Variasi Linked Lists
¨ Circular-linked lists: Node terakhir menyimpan
referensi node pertama. Dapat diterapkan dengan
atau tanpa header node.
prev
A B C
next
first
Doubly-linked lists: InsertNext
a 2 b
?
1 x
current
Doubly-linked lists: insertNext
A B
4
prev 3
2 X 5
current 1 next
6
newNode
1 newNode = new
DoublyLinkedListNode(x);
2 newNode.prev = current;
3 newNode.next = current.next;
4 newNode.prev.next = newNode;
5 newNode.next.prev = newNode;
6 current = newNode;
Doubly-linked lists: DeleteCurrent
1. current.prev.next = current.next;
2. current.next.prev = current.prev;
3. current = current.prev;
1
a b
2
3
current
x
Rangkuman
¨ ListNode
¨ List, LinkedList dan variasinya
¨ Iterator class
¨ Kelebihan & kekurangan dari linked list
¤ Growable
¤ Overhead a pointer, new operator untuk membuat
node.
¤ Hanya bisa diakses secara sequential.
Next…
Stack and Queue
source
¨ Slide fasilkom UI
¨ Slide tambahan lain