Struktur Data & Algoritme Objectives Outline Data Structure

6 downloads 171 Views 4MB Size Report
dapat memahami pentingnya penggunaan struktur data yang tepat dalam program. ▫ dapat memahami cara kerja Linked-List dan analisa kompleksitas waktu ...
Objectives Struktur Data & Algoritme (Data Structures & Algorithms)

„ „ „

dapat memahami pentingnya penggunaan struktur data yang tepat dalam program dapat memahami cara kerja Linked-List dan analisa kompleksitas waktu insert, delete dan akses dapat membuat/implementasi Linked-List

Linked-List

Denny ([email protected]) Suryana Setiawan ([email protected]) Fakultas Ilmu Komputer Universitas Indonesia Semester Genap - 2004/2005

Version 2.0 - Internal Use Only

Data Structure

Outline „ „ „ „

SDA/LL/V2.0/2

Importance and properties of Data Structure Basics of Linked Lists vs. Array Linked Lists and Iterators Linked Lists variant: „ Doubly Linked Lists „ Circular Linked Lists „ Sorted Linked Lists

„ „

Algorithms require the use of a proper representation of data to achieve efficiency Data structure (aka ADT – Abstract Data Type) = representation + operations „ operation allowed may vary between data structure • • • • „

SDA/LL/V2.0/3

insert delete access update

Kita perlu menganalisa waktu yang dibutuhkan untuk setiap operasi tersebut.

SDA/LL/V2.0/4

1

Mengapa Butuh Struktur Data „ „

Struktur data membantu tercapainya Component Reusability. Menerapkan konsep OO paradigm: encapsulation, informationhiding dan abstraction.

Macam Struktur Data yang Umum „ „ „ „

„ „

linked lists stacks queues trees „ binary search trees „ AVL trees „ B-Trees „ Trie hash tables priority queues

SDA/LL/V2.0/5

Linked Lists „ „ „ „

„

SDA/LL/V2.0/6

ListNode: Definition

Stores a collection of items non-contiguously. Each item in the list is stored with an indication of where the next item is. Must know where first item is. The list will be a chain of objects of type ListNode that contain the data and a reference to the next ListNode in the list. Allows addition or deletion of items in the middle of collection with only a constant amount of data movement. Contrast this with array.

public class ListNode { Object element; // some element ListNode next; // constructors ListNode (Object theElement, ListNode n) { element = theElement; next = n; } ListNode (Object theElement) { this (theElement, null); } ListNode () { this (null, null); }

ListNode

A0

A1

A2

A3 }

first

last

SDA/LL/V2.0/7

SDA/LL/V2.0/8

2

Linked List: Insertion

Insertion’s Steps „

a

b

c

d

// create a new node tmp = new ListNode( ); // place x in the element field tmp.element = x; // x’s next node is b tmp.next = current.next; // a’s next node is x current.next = tmp;

current

„

Insert X immediately after current position a

b

c

Insertion immediately after current position

d a

b

x

current

current

x

SDA/LL/V2.0/9

Insertion’s Steps „

Simplification of insertion’s code

Insertion immediately after current position

„

// create a new node tmp = new ListNode( ); // place x in the element field tmp.element = x; // x’s next node is b tmp.next = current.next; // a’s next node is x current.next = tmp;

a current

SDA/LL/V2.0/10

More efficient approach tmp = new ListNode (x, current.next); a current

b x

current.next = tmp; a

b

current

x SDA/LL/V2.0/11

b x SDA/LL/V2.0/12

3

Simplification of insertion’s code „

Linked List: append „

Most efficient approach

Insert X immediately at the end of the list // last refers to the last node in the linked list last.next = new ListNode(); last = last.next; // adjust last last.element = x; // place x in the node last.next = null; // adjust next

current.next = new ListNode (x, current.next);

a

b

c

d last

a „

b

c

d

X last

Most efficient approach

last = last.next = new ListNode (x, null); SDA/LL/V2.0/13

Linked Lists: Basic Deletion „ „

SDA/LL/V2.0/14

Deletion’s Steps

Delete an item immediately after current position Basic deletion is a bypass in the linked list.

„

Need a reference to node prior to the one to be deleted. current.next = current.next.next;

a

x

a

b

b

x

b

current

current a

x

a

b

current

current

a SDA/LL/V2.0/15

current

b SDA/LL/V2.0/16

4

Important Note „

Iterate the Linked List

Ingat!!! Yang disimpan dalam ListNode adalah reference dari object-nya, BUKAN object-nya itu sendiri atau salinan dari object-nya

„

Jika item disimpan dalam contiguous array: //step through array a, outputting each item for (int index = 0; index < a.length; index++) System.out.println (a[index]);

„

Jika item disimpan dalam sebuah linked list: // step through List theList, outputting each item for (ListNode p = theList.first; p != null; p = p.next) { System.out.println (p.data); }

A0 first

SDA/LL/V2.0/17

Header Nodes „ „

„

A2

A3 last

SDA/LL/V2.0/18

Linked Lists: List interface

Deletion of first item and insertion of new first item are special cases. Can be avoided by using header node; „ contains no data, but serves to ensure that first "real" node in linked has a predecessor. „ Go to the first element = current set to header.next; „ Empty list if header.next == null; Searching routines will skip header.

public interface List { /** Test if the list is logically empty. @return true if empty, false otherwise. */ boolean isEmpty (); /** Make the list logically empty. */ void makeEmpty ();

Header A

A1

B

C

}

SDA/LL/V2.0/19

SDA/LL/V2.0/20

5

Linked Lists: List implementation

Linked Lists: List implementation

public class LinkedList implements List { // friendly data, so LinkedListItr can have access ListNode header;

/** Make the list logically empty. */ public void makeEmpty( ) { header.next = null; }

/** Construct the list */ public LinkedList () { header = new ListNode (null); }

}

/** Test if the list is logically empty. @return true if empty, false otherwise. */ public boolean isEmpty( ) { return header.next == null; } SDA/LL/V2.0/21

Iterator Class „ „ „

SDA/LL/V2.0/22

Iterator Class

Maintains notion of the current position (aka cursor). List class provides method that do not depend on any position (such as isEmpty, and makeEmpty). List iterator (ListItr) provides most other methods such as advance, retrieve, first, which act on the current position stored in the iterator.

SDA/LL/V2.0/23

// 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() „

Exceptions thrown for illegal access, insert, or remove.

SDA/LL/V2.0/24

6

Example „

Java Implementations

A static member function that computes the number of elements in any list:

public static int listSize (List theList) { int size = 0; ListItr itr = new ListItr (theList);

„ „ „

Mostly straightforward; all routines are short. ListItr maintains a reference to the list that it is bound to as a private data member. Because ListItr is in the same package as List, if List's data is friendly, it can be accessed by ListItr.

for (itr.first(); itr.isInList(); itr.advance()) { size++; } return size; }

SDA/LL/V2.0/25

LinkedListItr implementation „

public class LinkedListItr implements ListItr

/** contains List header. */ protected LinkedList theList; /** stores current position. */ protected ListNode current; /** 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; } SDA/LL/V2.0/27

SDA/LL/V2.0/26

/** 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; } SDA/LL/V2.0/28

7

/** * 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; }

/** * 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" ); ListNode newNode = new ListNode( x, current.next ); current = current.next = newNode; }

/** * 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; }

SDA/LL/V2.0/29

/** * Set the current position to the first node containing an item. * current is unchanged if x is not found. * @param x the item to search for. * @return true if the item is found, false otherwise. */ public boolean find( Object x ) { ListNode itr = theList.header.next;

SDA/LL/V2.0/30

/** * 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;

while( itr != null && !itr.element.equals( x ) ) itr = itr.next;

while( itr.next != null && !itr.next.element.equals( x ) ) itr = itr.next;

if( itr == null ) return false;

if( itr.next == null ) throw new ItemNotFound( "Remove fails" );

current = itr; return true;

itr.next = itr.next.next; current = theList.header;

}

// Bypass deleted node // Reset current

}

SDA/LL/V2.0/31

SDA/LL/V2.0/32

8

Note on Exceptions /** * Remove the item after the current position. * current is unchanged. * @return true if successful false otherwise. */ public boolean removeNext( ) { if( current == null || current.next == null ) return false; current.next = current.next.next; return true; }

„ „

Some routines throw ItemNotFound exceptions. However, do not overuse exceptions, because they must always be caught or propagated. As an example, advance does not throw an exception, even if we have already advanced past the end. Otherwise, listSize would need a try/catch block.

/** * 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; } SDA/LL/V2.0/33

Linked List Properties „

„

„

SDA/LL/V2.0/34

Cetak Isi Linked List

Running Time Analysis „ insert next, prepend - O(1) „ delete next, delete first - O(1) „ find - O(n) „ retrieve current position - O(1) Advantages „ Growable (compared to array) „ Cepat mengakses/insert/delete elemen terdepan dan terbelakang (jika menyimpan juga posisi terbelakang) Disadvantages „ Sering memanggil operator new (compare to array) „ overhead one reference for each node SDA/LL/V2.0/35

„

Cara 1: Tanpa Iterator, Iteratif public class LinkedList { public void print () { // step through list, outputting each item ListNode p = header.next; while (p != null) { System.out.println (p.data); p = p.next; } }

SDA/LL/V2.0/36

9

Cetak Isi Linked List (2) „

Cetak Isi Linked List (3)

Cara 2: Tanpa Iterator, Rekursif

„

class ListNode { ... public void print () { System.out.println (data); if (next != null) { next.print (); } } } // end of class ListNode

public void print () { printRec (header.next); } }

class LinkedList { public void print () { if (header.next != null) { header.next.print (); } } }

SDA/LL/V2.0/37

Cetak Isi Linked List (4) „

Cara 3: “rekursif”

public class LinkedList { ... private static void printRec (ListNode node) { if (node != null) { System.out.println (node.data); printRec (node.next); } }

SDA/LL/V2.0/38

Sorted Linked Lists

Cara 4: menggunakan iterator

„

class LinkedList { ...

„

public void print (List theList) { ListItr itr = new ListItr (theList);

„

for (itr.first(); itr.isInList(); itr.advance()) { System.out.println (itr.retrieve ()); }

„

Maintains items in sorted order. Almost all operations are same as linked lists, except for insert. In fact, a sorted linked list IS-A linked list, suggesting that inheritance may be used. Extend a SortListItr from ListItr. However, items in a sorted linked list should be Comparable.

} }

SDA/LL/V2.0/39

SDA/LL/V2.0/40

10

Simple Implementation „

Important Note

Use inheritance, and create Insert method

„

ListItr used the equals member function in find and remove. Must make sure MyInteger has an equals member function if we are storing a linked list of MyIntegers. Signature MUST BE

„

The following signature is wrong!

„

If you try it, the method from class Object will be inherited and used:

„

public void insert( Comparable X ) „

„

Note however, that in this implementation, we have no assurance that the list is sorted, because it can be accessed by either a SortListItr or a ListItr. See the textbook for details.

„

public boolean equals( Object Rhs ) public boolean equals( Comparable Rhs )

public boolean equals (Object obj) { return (this == obj); } SDA/LL/V2.0/41

Other Linked Lists „

Doubly-linked lists: Wrong InsertNext

Doubly-linked lists: Each list node stores both the previous and next nodes in the list. Useful for traversing linked lists in both directions. prev

A next

head „

newNode = new DoublyLinkedListNode ( x ); 1 newNode.prev = current; 2 newNode.prev.next = newNode; … …

tail

Circular-linked lists: Last node's next references the first node. Works with or without headers.

a

B

b

2 1

prev

A

SDA/LL/V2.0/42

x

C

next

first SDA/LL/V2.0/43

SDA/LL/V2.0/44

11

Doubly-linked lists: insertNext

Doubly-linked lists: DeleteCurrent 1.

A

4 2

current 6

prev

B

3

X

2. 3.

5

current.prev.next = current.next; current.next.prev = current.prev; current = current.prev;

1 next

newNode 1 2 3 4 5 6

1

newNode = new DoublyLinkedListNode (x); newNode.prev = current; newNode.next = current.next; newNode.prev.next = newNode; newNode.next.prev = newNode; current = newNode;

a 3 current

SDA/LL/V2.0/45

JDK: package java.util „ „

2

b

x

SDA/LL/V2.0/46

Summary

Collection - List - LinkedList Iterator - ListIterator

„ „ „

„

SDA/LL/V2.0/47

ListNode List, LinkedList Iterator class „ a class that maintains a current position and performs all routines that depend on knowing the position in the list. Advantage & Disadvantage of linked list „ Growable „ Overhead a pointer, new operator „ Sequential access only

SDA/LL/V2.0/48

12

Further Reading „

„

„

What’s Next

Cari dan pelajari struktur data yang telah tersedia di Java API http://telaga.cs.ui.ac.id/WebKuliah/java5/ docs/api/java/util/package-summary.html Generics in Java 2 SE 5: http://telaga.cs.ui.ac.id/WebKuliah/java5/ Java5-Generics.pdf

„

Stacks & Queues - Chapter 6, 15, 11

Chapter 6 & 16

SDA/LL/V2.0/49

SDA/LL/V2.0/50

13