1 / 97

Building Java Programs Chapter 16

Building Java Programs Chapter 16. Linked Lists. A swap method?. Does the following swap method work? Why or why not? public static void main(String[] args) { int a = 7; int b = 35; // swap a with b swap(a, b); System.out.println(a + " " + b); }

mauricer
Télécharger la présentation

Building Java Programs Chapter 16

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Building Java ProgramsChapter 16 Linked Lists

  2. A swap method? • Does the following swap method work? Why or why not? public static void main(String[] args) { int a = 7; int b = 35; // swap a with b swap(a, b); System.out.println(a + " " + b); } public static void swap(int a, int b) { int temp = a; a = b; b = temp; }

  3. Value semantics • value semantics: Behavior where values are copied when assigned to each other or passed as parameters. • When one primitive is assigned to another, its value is copied. • Modifying the value of one variable does not affect others. int x = 5; int y = x; // x = 5, y = 5 y = 17; // x = 5, y = 17 x = 8; // x = 8, y = 17

  4. Reference semantics a1 a2 • reference semantics: Behavior where variables actually store the address of an object in memory. • When one reference variable is assigned to another, the object is not copied; both variables refer to the same object. int[] a1 = {4, 5, 2, 12, 14, 14, 9}; int[] a2 = a1; // refers to same array as a1 a2[0] = 7; System.out.println(a1[0]); // 7

  5. References and objects panel1 panel2 • In Java, objects and arrays use reference semantics. Why? • efficiency. Copying large objects slows down a program. • sharing. It's useful to share an object's data among methods. DrawingPanel panel1 = new DrawingPanel(80, 50); DrawingPanel panel2 = panel1; // same window panel2.setBackground(Color.CYAN);

  6. References as fields private Queue<HtmlTag> tags; ... HtmlValidator front ... ... ... back Queue HtmlTag HtmlTag private String element; ... private String element; ... h t m l String b o d y String • Objects can store references to other objects as fields. Example: Homework 3 (HTML Validator) • HtmlValidator stores a reference to a Queue • the Queue stores many references to HtmlTag objects • each HtmlTag object stores a reference to its element String

  7. Null references • null : A value that does not refer to any object. • The elements of an array of objects are initialized to null. String[] words = new String[5]; • not the same as the empty string "" or the string "null" • Why does Java have null ? What is it used for? words

  8. Null references • Unset reference fields of an object are initialized to null. public class Student { String name; int id; } Student timmy = new Student(); timmy

  9. Things you can do w/ null • store null in a variable or an array element String s = null; words[2] = null; • print a null reference System.out.println(timmy.name); // null • ask whether a variable or array element is null if (timmy.name == null) { ... // true • pass null as a parameter to a method • some methods don't like null parameters and throw exceptions • return null from a method (often to indicate failure) return null;

  10. Dereferencing • dereference: To access data or methods of an object. • Done with the dot notation, such as s.length() • When you use a . after an object variable, Java goes to the memory for that object and looks up the field/method requested. Student timmy = new Student(); timmy.name = "Timmah"; String s = timmy.name.toUpperCase(); Student String timmy public int indexOf(String s) {...} public int length() {...} public String toUpperCase() {...}

  11. Null pointer exception • It is illegal to dereference null (it causes an exception). • null does not refer to any object, so it has no methods or data. Student timmy = new Student(); String s = timmy.name.toUpperCase(); // ERROR Output: Exception in thread "main" java.lang.NullPointerException at Example.main(Example.java:8) timmy

  12. References to same type • What would happen if we had a class that declared one of its own type as a field? public class Strange { private String name; private Strange other; } • Will this compile? • If so, what is the behavior of the other field? What can it do? • If not, why not? What is the error and the reasoning behind it?

  13. Linked data structures • All of the collections we will use and implement in this course use one of the following two underlying data structures: • an array of all elements • ArrayList, Stack, HashSet, HashMap • a set of linked objects, each storing one element,and one or more reference(s) to other element(s) • LinkedList, TreeSet, TreeMap front

  14. A list node class public class ListNode { int data; ListNode next; } • Each list node object stores: • one piece of integer data • a reference to another list node • ListNodes can be "linked" into chains to store a list of values:

  15. List node client example public class ConstructList1 { public static void main(String[] args) { ListNode list = new ListNode(); list.data = 42; list.next = new ListNode(); list.next.data = -3; list.next.next = new ListNode(); list.next.next.data = 17; list.next.next.next = null; System.out.println(list.data + " " + list.next.data + " " + list.next.next.data); // 42 -3 17 } } list

  16. List node w/ constructor public class ListNode { int data; ListNode next; public ListNode(int data) { this.data = data; this.next = null; } public ListNode(int data, ListNode next) { this.data = data; this.next = next; } } • Exercise: Modify the previous client to use these constructors.

  17. Linked node problem 1 • What set of statements turns this picture: • Into this? list list

  18. Linked node problem 2 • What set of statements turns this picture: • Into this? list list

  19. Linked node problem 3 • What set of statements turns this picture: • Into this? list1 list2 list1 list2

  20. Linked node problem 4 • What set of statements turns this picture: • Into this? list ... list ...

  21. References vs. objects variable = value; a variable (left side of = ) is an arrow (the base of an arrow) a value (right side of = ) is an object (a box; what an arrow points at) • For the list at right: • a.next = value;means to adjust where points • variable = a.next;means to make variable point at 2 a 1 1 2

  22. Reassigning references • when you say: • a.next = b.next; • you are saying: • "Make the variable a.next refer to the same value as b.next." • Or, "Make a.next point to the same place that b.next points." a b

  23. Linked node question • Suppose we have a long chain of list nodes: • We don't know exactly how long the chain is. • How would we print the data values in all the nodes? list ...

  24. Algorithm pseudocode • Start at the front of the list. • While (there are more nodes to print): • Print the current node's data. • Go to the next node. • How do we walk through the nodes of the list? list = list.next; // is this a good idea? list ...

  25. Traversing a list? • One (bad) way to print every value in the list: while (list != null) { System.out.println(list.data); list = list.next; // move to next node } • What's wrong with this approach? • (It loses the linked list as it prints it!) list ...

  26. A current reference current • Don't change list. Make another variable, and change that. • A ListNode variable is NOT a ListNode object ListNode current = list; • What happens to the picture above when we write: current = current.next; list ...

  27. Traversing a list correctly • The correct way to print every value in the list: ListNode current = list; while (current != null) { System.out.println(current.data); current = current.next; // move to next node } • Changing current does not damage the list. list ...

  28. Algorithm to print list values: ListNode front = ...; ListNode current = front; while (current != null) { System.out.println(current.data); current = current.next; } Similar to array code: int[] a = ...; int i = 0; while (i < a.length) { System.out.println(a[i]); i++; } Linked list vs. array

  29. A LinkedIntList class • Let's write a collection class named LinkedIntList. • Has the same methods as ArrayIntList: • add, add, get, indexOf, remove, size, toString • The list is internally implemented as a chain of linked nodes • The LinkedIntList keeps a reference to its front as a field • null is the end of the list; a null front signifies an empty list LinkedIntList ListNode ListNode ListNode front add(value) add(index, value) indexOf(value) remove(index) size() toString() element 0 element 1 element 2

  30. LinkedIntList class v1 public class LinkedIntList { private ListNode front; public LinkedIntList() { front = null; } methods go here } LinkedIntList front =

  31. Implementing add // Adds the given value to the end of the list. public void add(int value) { ... } • How do we add a new node to the end of a list? • Does it matter what the list's contents are before the add? front = element 0 element 1 element 2

  32. Adding to an empty list • Before adding 20: After: • We must create a new node and attach it to the list. front = front = element 0

  33. The add method, 1st try // Adds the given value to the end of the list. public void add(int value) { if (front == null) { // adding to an empty list front = new ListNode(value); } else { // adding to the end of an existing list ... } }

  34. Adding to non-empty list • Before adding value 20 to end of list: • After: front = element 0 element 1 front = element 0 element 1 element 2

  35. Don't fall off the edge! • To add/remove from a list, you must modify the next reference of the node before the place you want to change. • Where should current be pointing, to add 20 at the end? • What loop test will stop us at this place in the list? front = element 0 element 1

  36. The add method // Adds the given value to the end of the list. public void add(int value) { if (front == null) { // adding to an empty list front = new ListNode(value); } else { // adding to the end of an existing list ListNode current = front; while (current.next != null) { current = current.next; } current.next = new ListNode(value); } }

  37. Implementing get // Returns value in list at given index. public int get(int index) { ... } • Exercise: Implement the get method. front = element 0 element 1 element 2

  38. The get method // Returns value in list at given index. // Precondition: 0 <= index < size() public int get(int index) { ListNode current = front; for (int i = 0; i < index; i++) { current = current.next; } return current.data; }

  39. Implementing add (2) // Inserts the given value at the given index. public void add(int index, int value) { ... } • Exercise: Implement the two-parameter add method. front = element 0 element 1 element 2

  40. The add method (2) // Inserts the given value at the given index. // Precondition: 0 <= index <= size() public void add(int index, int value) { if (index == 0) { // adding to an empty list front = new ListNode(value, front); } else { // inserting into an existing list ListNode current = front; for (int i = 0; i < index - 1; i++) { current = current.next; } current.next = new ListNode(value, current.next); } }

  41. Conceptual questions • What is the difference between a LinkedIntList and a ListNode? • What is the difference between an empty list and a null list? • How do you create each one? • Why are the fields of ListNode public? Is this bad style? • What effect does this code have on a LinkedIntList? ListNode current = front; current = null;

  42. Conceptual answers • A list consists of 0 to many node objects. • Each node holds a single data element value. • null list: LinkedIntList list = null;empty list: LinkedIntList list = new LinkedIntList(); • It's okay that the node fields are public, because client code never directly interacts with ListNode objects. • The code doesn't change the list.You can change a list only in one of the following two ways: • Modify its front field value. • Modify the next reference of a node in the list.

  43. Implementing remove // Removes and returns the list's first value. public int remove() { ... } • How do we remove the front node from a list? • Does it matter what the list's contents are before the remove?

  44. Removing front element • Before removing front element: • After first removal: After second removal: front = element 0 element 1 front = front = element 0

  45. remove solution // Removes and returns the first value. // Throws a NoSuchElementException on empty list. public int remove() { if (front == null) { throw new NoSuchElementException(); } else { int result = front.data; front = front.next; return result; } }

  46. Implementing remove (2) // Removes value at given index from list. // Precondition: 0 <= index < size public void remove(int index) { ... } • How do we remove any node in general from a list? • Does it matter what the list's contents are before the remove?

  47. Removing from a list • Before removing element at index 1: • After: front = element 0 element 1 element 2 front = element 0 element 1

  48. Removing from the front • Before removing element at index 0: • After: front = element 0 element 1 element 2 front = element 0 element 1

  49. Removing the only element • Before: After: • We must change the front field to store null instead of a node. • Do we need a special case to handle this? front = front = element 0

  50. remove (2) solution // Removes value at given index from list. // Precondition: 0 <= index < size() public void remove(int index) { if (index == 0) { // special case: removing first element front = front.next; } else { // removing from elsewhere in the list ListNode current = front; for (int i = 0; i < index - 1; i++) { current = current.next; } current.next = current.next.next; } }

More Related