Presentation is loading. Please wait.

Presentation is loading. Please wait.

CSCI 3333 Data Structures Linked Lists

Similar presentations


Presentation on theme: "CSCI 3333 Data Structures Linked Lists"— Presentation transcript:

1 CSCI 3333 Data Structures Linked Lists
by Dr. Bun Yue Professor of Computer Science

2 Acknowledgement Mr. Charles Moen Dr. Wei Ding Ms. Krishani Abeysekera
Dr. Michael Goodrich

3 Static Data Structures
The size of static data structures do not change. Example: array. During runtime, if there are more elements to be stored in an array: A new array needs to be created. The old array may be deleted. Elements are copied. Expensive!

4 Dynamic Data Structures
The size of a dynamic data structure can change during runtime. Many applications need to use dynamic data structures.

5 Linked List ADT A linked list is a sequence of nodes linked in a chain. Some operations: Create Delete Traverse Insert a node Delete a node Insert a linked list Delete a linked list

6 Linked Lists vs. Arrays Advantages: Disadvantages:
Dynamic: size changes on demand. Insertion and deletion of nodes: can be faster in some situations. Disadvantages: May not be randomly accessible efficiently. Options: Programmers needs to manage memory. Automatic garbage collection may bring performance issues.

7 Linked List ADT There are many kinds of linked lists implemented by different languages. They are different ADTs. We can study the ADTs to use them without knowing how they are implemented.

8 Example: C++ STL list Some methods:
begin: returns an iterator addressing the first element in a list. pop_back:deletes the element at the end of a list. pop_front: deletes the element at the beginning of a list. push_back: adds an element to the end of a list. push_front: adds an element to the beginning of a list. assign Erases elements from a list and copies a new set of elements to the target list. back Returns a reference to the last element of a list. begin Returns an iterator addressing the first element in a list. clear Erases all the elements of a list. empty Tests if a list is empty. end Returns an iterator that addresses the location succeeding the last element in a list. erase Removes an element or a range of elements in a list from specified positions. front Returns a reference to the first element in a list. get_allocator Returns a copy of the allocator object used to construct a list. insert Inserts an element or a number of elements or a range of elements into a list at a specified position. max_size Returns the maximum length of a list. merge Removes the elements from the argument list, inserts them into the target list, and orders the new, combined set of elements in ascending order or in some other specified order. pop_back Deletes the element at the end of a list. pop_front Deletes the element at the beginning of a list. push_back Adds an element to the end of a list. push_front Adds an element to the beginning of a list. rbegin Returns an iterator addressing the first element in a reversed list. remove Erases elements in a list that match a specified value. remove_if Erases elements from the list for which a specified predicate is satisfied. rend Returns an iterator that addresses the location succeeding the last element in a reversed list. resize Specifies a new size for a list. reverse Reverses the order in which the elements occur in a list. size Returns the number of elements in a list. sort Arranges the elements of a list in ascending order or with respect to some other order relation. splice Removes elements from the argument list and inserts them into the target list. swap Exchanges the elements of two lists. unique Removes adjacent duplicate elements or adjacent elements that satisfy some other binary predicate from the list.

9 Example Program #include <list> #include <iostream>
using namespace std ; typedef list<int> INT_LIST; int main() { INT_LIST ilist; ilist.push_back(1); ilist.push_front(2); ilist.push_front(3); ilist.push_front(4); ilist.push_back(5); cout << ilist.front() << endl; cout << ilist.back() << endl;

10 Example Program (cont)
INT_LIST::iterator i; cout << "Int list content:"; for (i = ilist.begin(); i != ilist.end(); ++i) cout << " " << *i; // Note * cout << endl; (*i)++; ilist.pop_front(); ilist.pop_back(); }

11 Output 1 ilist.push_back(1); ilist.push_front(2); ilist.push_front(3);
cout << ilist.front() << endl; cout << ilist.back() << endl; Output: 4 5

12 Output 2 INT_LIST::iterator i; cout << "Int list content:";
for (i = ilist.begin(); i != ilist.end(); ++i) cout << " " << *i; // Note * cout << endl; (*i)++; Output: Int list content: Int list content:

13 Output 3 ilist.pop_front(); ilist.pop_back();
cout << "Int list content:"; for (i = ilist.begin(); i != ilist.end(); ++i) cout << " " << *i; cout << endl; Output: Int list content: 4 3 2

14 Perl Example In Perl, an array is also a list.
It is built into the language. (You can see the importance of lists here.) Array/List variables start with the List elements are scalar (which starts with the symbol $), e.g. $a[1], $a[12], etc.

15 Perl’s List Examples @num[1,2] = (3,4); # $num[1] = 3; $num[2] = 4;
# swap $num[1] and $num[2]; @num[1,2] # $num[1] = $num[3]; $num[2] = $num[3]; ($num[1], $num[2]) = ($num[2], $num[1]); # swap $num[1] and $num[2]; @num = (1,2,3,4,5)[3,2,1]; = (4,3,2); # remove the first element into $first $last) # pop the last element to $last

16 Java’s List Interface ADT
Java has a List interface for ordered collection (sequence). Super-interface: Collection Iterable Some known implementation classes: AbstractList LinkedList ArrayList Vector Practical APIs are much richer than those found in some textbooks!

17 Interable Interface Target of a for each statement. One method only
Iterator<T>iterator(): returns an iterator over a set of elements of type T. Iterator<T> interface’s methods: hasNext() next() remove()

18 Collection Interface Group of objects, possibly with duplicates.
Super-interface: iterable. Some methods: add(E e) addAll(Collection<? extends E> c) contains(Object o) remove(Object o) removeAll(Collection<?> c) size() toArray() booleanadd(E e)           Ensures that this collection contains the specified element (optional operation). booleanaddAll(Collection<? extends E> c)           Adds all of the elements in the specified collection to this collection (optional operation). voidclear()           Removes all of the elements from this collection (optional operation). booleancontains(Object o)           Returns true if this collection contains the specified element. booleancontainsAll(Collection<?> c)           Returns true if this collection contains all of the elements in the specified collection. booleanequals(Object o)           Compares the specified object with this collection for equality. inthashCode()           Returns the hash code value for this collection. booleanisEmpty()           Returns true if this collection contains no elements. Iterator<E>iterator()           Returns an iterator over the elements in this collection. booleanremove(Object o)           Removes a single instance of the specified element from this collection, if it is present (optional operation). booleanremoveAll(Collection<?> c)           Removes all of this collection's elements that are also contained in the specified collection (optional operation). booleanretainAll(Collection<?> c)           Retains only the elements in this collection that are contained in the specified collection (optional operation). intsize()           Returns the number of elements in this collection. Object[]toArray()           Returns an array containing all of the elements in this collection.<T> T[]toArray(T[] a)           Returns an array containing all of the elements in this collection; the runtime type of the returned array is that of the specified array.

19 List Interface New required methods added: Random access: Searching:
E get(int index) E remove(int index) Searching: int indexOf(Object o) int lastIndexOf(Object o) List Iterator: ListIterator<E> listIterator()

20 Concrete Class LinkedList<E>
Interface implemented: Serializable Cloneable Iterable<E> Collection<E>  Queue<E>  Deque<E> Iterable<E>  Collection<E>  List<E> <E>: Actual E should be a class (not int, float, etc)

21 LinkedList Methods From implementing Dequeue: void addFirst(E e)
void addLast(E e) E removeFirst() E removeLast() E offerFirst(): retrieve, not remove, exception version for empty Dequeue. E peekFirst(): retrieve, not remove, return null version for empty Dequeue.

22 LinkedList Methods From implementing List: add(E e) E get(int index)
E remove(int index) remove(Object o) int indexOf(Object o)

23 Finding the Right Structures
APIs are usually feature rich. Study purposes of classes and interfaces. Study hierarchical class and interface structures. Study methods available.

24 Examples Good to critically read program code.

25 Implementation Issues
You do not need to know how classes are implemented to use them! However, knowing the implementations: May deepen understanding of the classes for better usages. May help selecting the best class for the application. May transfer this knowledge when you need to implement custom-designed classes yourself.

26 Example Implementation in C++
Singly linked list of float Each node has only one pointer to its successor. The list stores a head pointer to the head of the list. If the list is empty, the head pointer is null. For simplicity, each node stores an float.

27 Implementation issues
Data members: Value of float head pointer tail pointer: for efficiency size of the list: for efficiency. Tips: ensure all data members properly updated in operations.

28 Node class FloatList{ private: // Declare a structure for the list.
// Simliar to nested classes in Java struct ListNode { float value; struct ListNode *next; }; ListNode *head, *tail; // head and tail pointers int _size;

29 Method Prototypes public: FloatList() // Constructor
{ head = tail = NULL; _size = 0; } ~FloatList(); // Destructor Tips: always include constructors and destructors.

30 Method Prototypes void appendTailNode(float);
// insert node at the tail. bool deleteHeadNode(); // delete node at the head. bool deleteNode(float); // delete the first occurrence of the float // list. void displayList(); int size() { return _size; } bool isEmpty() { return _size == 0; } };

31 Method Implementations
void FloatList::appendTailNode(float num) { ListNode *newNode; // Allocate a new node & store num newNode = new ListNode; newNode->value = num; newNode->next = NULL; if (head==NULL) { // empty list head = tail = newNode; } else { tail->next = newNode; tail = tail-> next; _size++;

32 Discussion Maintenance of data members.
Trade off of using _size and tail: faster for some operations and slower for others. Definition of newNode as class instead of struct: use of constructors.

33 deleteHeadNode bool FloatList::deleteHeadNode() { if (head == NULL)
return false; else { ListNode *temp = head; head = head-> next; if (head == NULL) tail = NULL; delete temp; _size--; return true; }

34 Discussion Other possible methods: May change prototype:
deleteTailNode May change prototype:

35 deleteNode(float f) bool FloatList::deleteNode(float f) {
if (head == NULL) return false; else { ListNode *curr = head; ListNode *prev = NULL; while (curr != NULL && curr->value != f) { prev = curr; curr = curr-> next; } if (curr == NULL) // do not find the number to be deleted. else // to be continued.

36 else part { if (prev == NULL) { // the head node contains the number.
head = curr-> next; } if (curr == tail) { // the tail node will be deleted. tail = prev; // link the prev node to skip the curr node. prev->next = curr->next; delete curr; _size--; return true;

37 Discussion Other possible methods. deleteLastNode.

38 displayList void FloatList::displayList() { ListNode *nodePtr;
nodePtr = head; while (nodePtr) cout << nodePtr->value << " "; nodePtr = nodePtr->next; } cout << endl;

39 Discussion Not flexible. Need an ‘iterator’.

40 Destructor FloatList::~FloatList(){ ListNode *curr, *next;
curr = head; while (curr != NULL) { next = curr->next; delete curr; curr = next; }

41 Test Program FloatList list; list.appendTailNode(2.2);
list.displayList(); cout << "size: " << list.size() << endl; Output: size: 5

42 Test Program list.deleteHeadNode(); list.displayList();
cout << "size: " << list.size() << endl; list.deleteNode(2.2); Outpit: size: 4 size: 3 size: 2

43 Test Program list.deleteHeadNode(); list.displayList();
cout << "size: " << list.size() << endl; Output: size: 0

44 Discussion Other possible methods: getHeadNodeValue()
getTailNodeValue() deleteTailNode()

45 Discussion Some operations, deleteTailNode may take longer time, O(N), where N is the number of nodes in the list. May use a doubly linked list. Need to have a way to analyze performance. List only works for float May use template.

46 Questions and Comments?


Download ppt "CSCI 3333 Data Structures Linked Lists"

Similar presentations


Ads by Google