Top Banner
© 2010 Pearson Addison-Wesley. All rights reserved. Addison Wesley is an imprint of CHAPTER 4: Linked Structures Java Software Structures: Designing and Using Data Structures Third Edition John Lewis & Joseph Chase
47

CHAPTER 4: Linked Structures

Jan 05, 2016

Download

Documents

kare

CHAPTER 4: Linked Structures. Java Software Structures: Designing and Using Data Structures Third Edition John Lewis & Joseph Chase. Chapter Objectives. Describe the use of references to create linked structures Compare linked structures to array-based structures - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: CHAPTER 4:  Linked Structures

© 2010 Pearson Addison-Wesley. All rights reserved.

Addison Wesley is an imprint of

CHAPTER 4: Linked Structures

Java Software Structures:Designing and Using Data Structures

Third Edition

John Lewis & Joseph Chase

Page 2: CHAPTER 4:  Linked Structures

1-2

© 2010 Pearson Addison-Wesley. All rights reserved. 1-2

Chapter Objectives

• Describe the use of references to create linked structures

• Compare linked structures to array-based structures

• Explore the techniques for managing a linked list• Discuss the need for a separate node to form

linked structures• Implement a stack collection using a linked list

Page 3: CHAPTER 4:  Linked Structures

1-3

© 2010 Pearson Addison-Wesley. All rights reserved. 1-3

References as Links

• There are many ways to implement a collection• In chapter 3 we explored an array-based

implementation of a stack collection• A linked structure uses object reference

variables to link one object to another• Recall that an object reference variable stores

the address of an object• In that sense, an object reference is a pointer to

an object

Page 4: CHAPTER 4:  Linked Structures

1-4

© 2010 Pearson Addison-Wesley. All rights reserved. 1-4

References as Links

Page 5: CHAPTER 4:  Linked Structures

1-5

© 2010 Pearson Addison-Wesley. All rights reserved. 1-5

Self-Referential Objects

• A Person object, for instance, could contain a reference variable to another Person object:

public class Person{ private String name; private String address;

private Person next; // a link to another Person object

// whatever else

}

Page 6: CHAPTER 4:  Linked Structures

1-6

© 2010 Pearson Addison-Wesley. All rights reserved. 1-6

Linked Lists

• This type of reference can be used to form a linked list, in which one object refers to the next, which refers to the next, etc.

• Each object in a list is often generically called a node

• A linked list is a dynamic data structure in that its size grows and shrinks as needed, unlike an array, whose size is static or fixed

• Java objects are created dynamically when they are instantiated

Page 7: CHAPTER 4:  Linked Structures

1-7

© 2010 Pearson Addison-Wesley. All rights reserved. 1-7

A linked list

Page 8: CHAPTER 4:  Linked Structures

1-8

© 2010 Pearson Addison-Wesley. All rights reserved. 1-8

Non-linear Structures

• A linked list, as the name implies, is a linear structure

• Object references also allow us to create non-linear structures such as hierarchies and graphs

Page 9: CHAPTER 4:  Linked Structures

1-9

© 2010 Pearson Addison-Wesley. All rights reserved. 1-9

A complex linked structure

Page 10: CHAPTER 4:  Linked Structures

1-10

© 2010 Pearson Addison-Wesley. All rights reserved. 1-10

Managing Linked Lists

• The references in a linked list must be carefully managed to maintain the integrity of the structure

• Special care must be taken to ensure that the entry point into the list is maintained properly

• The order in which certain steps are taken is important

• Consider inserting and deleting nodes in various positions within the list

Page 11: CHAPTER 4:  Linked Structures

1-11

© 2010 Pearson Addison-Wesley. All rights reserved. 1-11

Inserting a node at the front of a linked list

Page 12: CHAPTER 4:  Linked Structures

1-12

© 2010 Pearson Addison-Wesley. All rights reserved. 1-12

Inserting a node in the middle of a linked list

Page 13: CHAPTER 4:  Linked Structures

1-13

© 2010 Pearson Addison-Wesley. All rights reserved. 1-13

Deleting the first node in a linked list

Page 14: CHAPTER 4:  Linked Structures

1-14

© 2010 Pearson Addison-Wesley. All rights reserved. 1-14

Deleting an interior node from a linked list

Page 15: CHAPTER 4:  Linked Structures

1-15

© 2010 Pearson Addison-Wesley. All rights reserved. 1-15

Elements without Links

• The problem with self-referential objects is that they must "know" they are part of a list

• A better approach is to manage a separate list of nodes that also reference the objects stored in the list

• The list is still managed using the same techniques

• The objects stored in the list need no special implementation to be part of the list

• A generic list collection can be used to store any kind of object

Page 16: CHAPTER 4:  Linked Structures

1-16

© 2010 Pearson Addison-Wesley. All rights reserved. 1-16

Using separate node objects to store and link elements

Page 17: CHAPTER 4:  Linked Structures

1-17

© 2010 Pearson Addison-Wesley. All rights reserved. 1-17

Sentinel nodes

• There are variations on the implementation of linked lists that may be useful in particular situations

• One such solution is the use of sentinel nodes or dummy nodes on either end of the list

• This practice eliminates the special cases of inserting or deleting the first or last node

Page 18: CHAPTER 4:  Linked Structures

1-18

© 2010 Pearson Addison-Wesley. All rights reserved. 1-18

Doubly Linked Lists

• Another useful variation is a doubly linked list

• In a doubly linked list each node has a reference to both the next and previous nodes in the list

• This makes traversing the list easier

Page 19: CHAPTER 4:  Linked Structures

1-19

© 2010 Pearson Addison-Wesley. All rights reserved. 1-19

A doubly linked list

Page 20: CHAPTER 4:  Linked Structures

1-20

© 2010 Pearson Addison-Wesley. All rights reserved. 1-20

Implementing a stack with links

• We can use a linked list to implement our stack collection from chapter 3

• First, however, we will need to create a LinearNode class to represent a node in the list

Page 21: CHAPTER 4:  Linked Structures

1-21

© 2010 Pearson Addison-Wesley. All rights reserved. 1-21

The LinearNode class/** * @author Lewis and Chase * * Represents a node in a linked list. */package jss2;

public class LinearNode<T>{ /** reference to next node in list */ private LinearNode<T> next; /** element stored at this node */ private T element; /** * Creates an empty node. */ public LinearNode() { next = null; element = null; }

/** * @author Lewis and Chase * * Represents a node in a linked list. */package jss2;

public class LinearNode<T>{ /** reference to next node in list */ private LinearNode<T> next; /** element stored at this node */ private T element; /** * Creates an empty node. */ public LinearNode() { next = null; element = null; }

Page 22: CHAPTER 4:  Linked Structures

1-22

© 2010 Pearson Addison-Wesley. All rights reserved. 1-22

The LinearNode class (continued) /** * Creates a node storing the specified element. * @param elem element to be stored */ public LinearNode (T elem) { next = null; element = elem; } /** * Returns the node that follows this one. * @return LinearNode<T> reference to next node */ public LinearNode<T> getNext() { return next; } /** * Sets the node that follows this one. * @param node node to follow this one */

/** * Creates a node storing the specified element. * @param elem element to be stored */ public LinearNode (T elem) { next = null; element = elem; } /** * Returns the node that follows this one. * @return LinearNode<T> reference to next node */ public LinearNode<T> getNext() { return next; } /** * Sets the node that follows this one. * @param node node to follow this one */

Page 23: CHAPTER 4:  Linked Structures

1-23

© 2010 Pearson Addison-Wesley. All rights reserved. 1-23

The LinearNode class (continued) public void setNext (LinearNode<T> node) { next = node; } /** * Returns the element stored in this node. * @return T element stored at this node */ public T getElement() { return element; } /** * Sets the element stored in this node. * @param elem element to be stored at this node */ public void setElement (T elem) { element = elem; }}

public void setNext (LinearNode<T> node) { next = node; } /** * Returns the element stored in this node. * @return T element stored at this node */ public T getElement() { return element; } /** * Sets the element stored in this node. * @param elem element to be stored at this node */ public void setElement (T elem) { element = elem; }}

Page 24: CHAPTER 4:  Linked Structures

1-24

© 2010 Pearson Addison-Wesley. All rights reserved. 1-24

A linked implementation of a stack collection

Page 25: CHAPTER 4:  Linked Structures

1-25

© 2010 Pearson Addison-Wesley. All rights reserved. 1-25

LinkedStack /** * @author Lewis and Chase * * Represents a linked implementation of a stack. */package jss2;import jss2.exceptions.*;import java.util.Iterator;

public class LinkedStack<T> implements StackADT<T>{ /** indicates number of elements stored */ private int count; /** pointer to top of stack */ private LinearNode<T> top;

/** * Creates an empty stack. */ public LinkedStack() { count = 0; top = null; }

/** * @author Lewis and Chase * * Represents a linked implementation of a stack. */package jss2;import jss2.exceptions.*;import java.util.Iterator;

public class LinkedStack<T> implements StackADT<T>{ /** indicates number of elements stored */ private int count; /** pointer to top of stack */ private LinearNode<T> top;

/** * Creates an empty stack. */ public LinkedStack() { count = 0; top = null; }

Page 26: CHAPTER 4:  Linked Structures

1-26

© 2010 Pearson Addison-Wesley. All rights reserved. 1-26

An initial stack

Page 27: CHAPTER 4:  Linked Structures

1-27

© 2010 Pearson Addison-Wesley. All rights reserved. 1-27

LinkedStack – the push operation

/** * Adds the specified element to the top of this stack. * @param element element to be pushed on stack */ public void push (T element) { LinearNode<T> temp = new LinearNode<T> (element);

temp.setNext(top); top = temp; count++; }

/** * Adds the specified element to the top of this stack. * @param element element to be pushed on stack */ public void push (T element) { LinearNode<T> temp = new LinearNode<T> (element);

temp.setNext(top); top = temp; count++; }

Page 28: CHAPTER 4:  Linked Structures

1-28

© 2010 Pearson Addison-Wesley. All rights reserved. 1-28

A Linked Stack After a Push Operation

Page 29: CHAPTER 4:  Linked Structures

1-29

© 2010 Pearson Addison-Wesley. All rights reserved. 1-29

LinkedStack – the pop operation

/** * Removes the element at the top of this stack and returns a * reference to it. Throws an EmptyCollectionException if the stack * is empty. * @return T element from top of stack * @throws EmptyCollectionException on pop from empty stack */ public T pop() throws EmptyCollectionException { if (isEmpty()) throw new EmptyCollectionException("Stack");

T result = top.getElement(); top = top.getNext(); count--; return result; }

/** * Removes the element at the top of this stack and returns a * reference to it. Throws an EmptyCollectionException if the stack * is empty. * @return T element from top of stack * @throws EmptyCollectionException on pop from empty stack */ public T pop() throws EmptyCollectionException { if (isEmpty()) throw new EmptyCollectionException("Stack");

T result = top.getElement(); top = top.getNext(); count--; return result; }

Page 30: CHAPTER 4:  Linked Structures

1-30

© 2010 Pearson Addison-Wesley. All rights reserved. 1-30

A Linked Stack After a Pop Operation

Page 31: CHAPTER 4:  Linked Structures

1-31

© 2010 Pearson Addison-Wesley. All rights reserved. 1-31

LinkedStack – the other operations

• Using a linked implementation, the peek operation is implemented by returning a reference to top

• The isEmpty operation returns true if the count of elements is 0, and false otherwise

• The size operation simply returns the count of elements in the stack

• The toString operation can be implemented by simply traversing the linked list.

Page 32: CHAPTER 4:  Linked Structures

1-32

© 2010 Pearson Addison-Wesley. All rights reserved. 1-32

Analysis of Stack Operations

• Like our ArrayStack operations, the LinkedStack operations work on one end of the collection and are generally efficient

• The push and pop operations, for the linked implementation are O(1)

• Likewise, the other operations are also O(1)

Page 33: CHAPTER 4:  Linked Structures

1-33

© 2010 Pearson Addison-Wesley. All rights reserved. 1-33

Using Stacks - Traversing a Maze

• A classic use of a stack is to keep track of alternatives in maze traversal or other trial and error algorithms

• Using a stack in this way simulates recursion – Recursion is when a method calls itself either

directly or indirectly

Page 34: CHAPTER 4:  Linked Structures

1-34

© 2010 Pearson Addison-Wesley. All rights reserved. 1-34

Using Stacks - Traversing a Maze

• Run-time environments keep track of method calls by placing an activation record for each called method on the run-time stack

• When a method completes execution, it is popped from the stack and control returns to the method that called it– Which is now the activation record on the top of the

stack

Page 35: CHAPTER 4:  Linked Structures

1-35

© 2010 Pearson Addison-Wesley. All rights reserved. 1-35

Using Stacks - Traversing a Maze

• In this manner, we can traverse a maze by trial and error by using a stack to keep track of moves that have not yet been tried

Page 36: CHAPTER 4:  Linked Structures

1-36

© 2010 Pearson Addison-Wesley. All rights reserved. 1-36

The Maze class

/** * @author Lewis and Chase * * Represents a maze of characters. The goal is to get from the * top left corner to the bottom right, following a path of 1's. */import jss2.*;

public class Maze{ /** * constant to represent tried paths */ private final int TRIED = 3; /** * constant to represent the final path */ private final int PATH = 7;

/** * @author Lewis and Chase * * Represents a maze of characters. The goal is to get from the * top left corner to the bottom right, following a path of 1's. */import jss2.*;

public class Maze{ /** * constant to represent tried paths */ private final int TRIED = 3; /** * constant to represent the final path */ private final int PATH = 7;

Page 37: CHAPTER 4:  Linked Structures

1-37

© 2010 Pearson Addison-Wesley. All rights reserved. 1-37

The Maze class (continued)

/** * two dimensional array representing the grid */ private int [][] grid = { {1,1,1,0,1,1,0,0,0,1,1,1,1}, {1,0,0,1,1,0,1,1,1,1,0,0,1}, {1,1,1,1,1,0,1,0,1,0,1,0,0}, {0,0,0,0,1,1,1,0,1,0,1,1,1}, {1,1,1,0,1,1,1,0,1,0,1,1,1}, {1,0,1,0,0,0,0,1,1,1,0,0,1}, {1,0,1,1,1,1,1,1,0,1,1,1,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0}, {1,1,1,1,1,1,1,1,1,1,1,1,1} }; /** * push a new attempted move onto the stack * @param x represents x coordinate * @param y represents y coordinate * @param stack the working stack of moves within the grid * @return StackADT<Position> stack of moves within the grid */

/** * two dimensional array representing the grid */ private int [][] grid = { {1,1,1,0,1,1,0,0,0,1,1,1,1}, {1,0,0,1,1,0,1,1,1,1,0,0,1}, {1,1,1,1,1,0,1,0,1,0,1,0,0}, {0,0,0,0,1,1,1,0,1,0,1,1,1}, {1,1,1,0,1,1,1,0,1,0,1,1,1}, {1,0,1,0,0,0,0,1,1,1,0,0,1}, {1,0,1,1,1,1,1,1,0,1,1,1,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0}, {1,1,1,1,1,1,1,1,1,1,1,1,1} }; /** * push a new attempted move onto the stack * @param x represents x coordinate * @param y represents y coordinate * @param stack the working stack of moves within the grid * @return StackADT<Position> stack of moves within the grid */

Page 38: CHAPTER 4:  Linked Structures

1-38

© 2010 Pearson Addison-Wesley. All rights reserved. 1-38

The Maze class (continued)

private StackADT<Position> push_new_pos(int x, int y, StackADT<Position> stack) { Position npos = new Position(); npos.setx(x); npos.sety(y); if (valid(npos.getx(),npos.gety())) stack.push(npos);

return stack; } /** * Attempts to iteratively traverse the maze. It inserts special * characters indicating locations that have been tried and that * eventually become part of the solution. This method uses a * stack to keep track of the possible moves that could be made. * @return boolean returns true if the maze is successfully traversed */

private StackADT<Position> push_new_pos(int x, int y, StackADT<Position> stack) { Position npos = new Position(); npos.setx(x); npos.sety(y); if (valid(npos.getx(),npos.gety())) stack.push(npos);

return stack; } /** * Attempts to iteratively traverse the maze. It inserts special * characters indicating locations that have been tried and that * eventually become part of the solution. This method uses a * stack to keep track of the possible moves that could be made. * @return boolean returns true if the maze is successfully traversed */

Page 39: CHAPTER 4:  Linked Structures

1-39

© 2010 Pearson Addison-Wesley. All rights reserved. 1-39

The Maze class (continued)

public boolean traverse () { boolean done = false; Position pos = new Position(); Object dispose; StackADT<Position> stack = new LinkedStack<Position>(); stack.push(pos); while (!(done)) { pos = stack.pop(); grid[pos.getx()][pos.gety()] = TRIED; // this cell has been tried if (pos.getx() == grid.length-1 && pos.gety() == grid[0].length-1) done = true; // the maze is solved else { stack = push_new_pos(pos.getx(),pos.gety() - 1, stack); stack = push_new_pos(pos.getx(),pos.gety() + 1, stack); stack = push_new_pos(pos.getx() - 1,pos.gety(), stack); stack = push_new_pos(pos.getx() + 1,pos.gety(), stack); } }

public boolean traverse () { boolean done = false; Position pos = new Position(); Object dispose; StackADT<Position> stack = new LinkedStack<Position>(); stack.push(pos); while (!(done)) { pos = stack.pop(); grid[pos.getx()][pos.gety()] = TRIED; // this cell has been tried if (pos.getx() == grid.length-1 && pos.gety() == grid[0].length-1) done = true; // the maze is solved else { stack = push_new_pos(pos.getx(),pos.gety() - 1, stack); stack = push_new_pos(pos.getx(),pos.gety() + 1, stack); stack = push_new_pos(pos.getx() - 1,pos.gety(), stack); stack = push_new_pos(pos.getx() + 1,pos.gety(), stack); } }

Page 40: CHAPTER 4:  Linked Structures

1-40

© 2010 Pearson Addison-Wesley. All rights reserved. 1-40

The Maze class (continued) return done; } /** * Determines if a specific location is valid. * @param row int representing y coordinate * @param column int representing x coordinate * @return boolean true if the given coordinate is a valid move */ private boolean valid (int row, int column) { boolean result = false; /** Check if cell is in the bounds of the matrix */ if (row >= 0 && row < grid.length && column >= 0 && column < grid[row].length) /** Check if cell is not blocked and not previously tried */ if (grid[row][column] == 1) result = true; return result; }

return done; } /** * Determines if a specific location is valid. * @param row int representing y coordinate * @param column int representing x coordinate * @return boolean true if the given coordinate is a valid move */ private boolean valid (int row, int column) { boolean result = false; /** Check if cell is in the bounds of the matrix */ if (row >= 0 && row < grid.length && column >= 0 && column < grid[row].length) /** Check if cell is not blocked and not previously tried */ if (grid[row][column] == 1) result = true; return result; }

Page 41: CHAPTER 4:  Linked Structures

1-41

© 2010 Pearson Addison-Wesley. All rights reserved. 1-41

The Maze class (continued) /** * Returns the maze as a string. * @return String representation of the maze grid */ public String toString () { String result = "\n"; for (int row=0; row < grid.length; row++) { for (int column=0; column < grid[row].length; column++) result += grid[row][column] + ""; result += "\n"; } return result; }}

/** * Returns the maze as a string. * @return String representation of the maze grid */ public String toString () { String result = "\n"; for (int row=0; row < grid.length; row++) { for (int column=0; column < grid[row].length; column++) result += grid[row][column] + ""; result += "\n"; } return result; }}

Page 42: CHAPTER 4:  Linked Structures

1-42

© 2010 Pearson Addison-Wesley. All rights reserved. 1-42

The MazeSearch class /** * @author Lewis and Chase * * Demonstrates a simulation of recursion using a stack. */

public class MazeSearch{ /** * Creates a new maze, prints its original form, attempts to * solve it, and prints out its final form. * @param args array of Strings */ public static void main (String[] args) { Maze labyrinth = new Maze(); System.out.println (labyrinth); if (labyrinth.traverse ()) System.out.println ("The maze was successfully traversed!"); else System.out.println ("There is no possible path."); System.out.println (labyrinth); }}

/** * @author Lewis and Chase * * Demonstrates a simulation of recursion using a stack. */

public class MazeSearch{ /** * Creates a new maze, prints its original form, attempts to * solve it, and prints out its final form. * @param args array of Strings */ public static void main (String[] args) { Maze labyrinth = new Maze(); System.out.println (labyrinth); if (labyrinth.traverse ()) System.out.println ("The maze was successfully traversed!"); else System.out.println ("There is no possible path."); System.out.println (labyrinth); }}

Page 43: CHAPTER 4:  Linked Structures

1-43

© 2010 Pearson Addison-Wesley. All rights reserved. 1-43

The Position class /** * @author Lewis and Chase * * Represents a single position in a maze of characters. */

public class Position{ /** x coordinate */ private int x; /** y coordinate */ private int y;

/** * Constructs a position and sets the x & y coordinates to 0,0. */ Position () { x = 0; y = 0; }

/** * @author Lewis and Chase * * Represents a single position in a maze of characters. */

public class Position{ /** x coordinate */ private int x; /** y coordinate */ private int y;

/** * Constructs a position and sets the x & y coordinates to 0,0. */ Position () { x = 0; y = 0; }

Page 44: CHAPTER 4:  Linked Structures

1-44

© 2010 Pearson Addison-Wesley. All rights reserved. 1-44

The Position class (continued) /** * Returns the x-coordinate value of this position. * @return int the x-coordinate of this position */ public int getx() { return x; }

/** * Returns the y-coordinate value of this position. * @return int the y-coordinate of this position */ public int gety() { return y; }

/** * Returns the x-coordinate value of this position. * @return int the x-coordinate of this position */ public int getx() { return x; }

/** * Returns the y-coordinate value of this position. * @return int the y-coordinate of this position */ public int gety() { return y; }

Page 45: CHAPTER 4:  Linked Structures

1-45

© 2010 Pearson Addison-Wesley. All rights reserved. 1-45

The Position class (continued) /** * Sets the value of the current position's x-coordinate. * @param a value of x-coordinate */ public void setx(int a) { x = a; }

/** * Sets the value of the current position's x-coordinate. * @param a value of y-coordinate */ public void sety(int a) { y = a; }}

/** * Sets the value of the current position's x-coordinate. * @param a value of x-coordinate */ public void setx(int a) { x = a; }

/** * Sets the value of the current position's x-coordinate. * @param a value of y-coordinate */ public void sety(int a) { y = a; }}

Page 46: CHAPTER 4:  Linked Structures

1-46

© 2010 Pearson Addison-Wesley. All rights reserved. 1-46

The java.util.Stack Class

• The Java Collections framework defines a Stack class with similar operations

• It is derived from the Vector class and therefore has some characteristics that are not appropriate for a pure stack

• The java.util.Stack class has been around since the original version of Java, and has been retrofitted to meld with the Collections framework

Page 47: CHAPTER 4:  Linked Structures

1-47

© 2010 Pearson Addison-Wesley. All rights reserved. 1-47

A UML description of the java.util.Stack class