CS 240
Lab 4
Purpose: Practical
introduction to the List
ADT and its implementation using an array-based data structure.
Reading: Linked list
concepts are discussed
on pp. 287-294 in the text. An array-based
implementation of linked lists is discussed on pp. 303-308.
Motivation: The List ADT can be
implemented using either static
or dynamic arrays.
While either of these implementations may be adequate, they have their limitations. A static array stores list elements
in consecutive locations. It has a fixed size, which may be too
small or too large. Although a dynamic
array can be adjusted to any size, like a static array, it too stores list
elements in consecutive locations. Therefore, both require
extensive copying of values in order to implement insert and delete List ADT operations. Another
data structure that can be used to implement the List ADT is a linked list. Unlike static or dynamic arrays, linked lists permit insertions and
deletions without the need for extensive copying because consecutive elements in
the
list are NOT stored in consecutive locations. Rather, each
element -- along with a reference to the location of the next element
in
the list -- is part of a structure called a node. Think of it as the CS version of a Treasure Hunt!
Assignment: Design, implement, and test an ordered array-based
linked list (in an ordered list, all items are placed on the list by numeric or alphanumeric order)
- Develop file LinkedList.h
as follows:
- Using typedef
statements: define type Element
to be an int
and type Link
to be int
- Define constants NUMNODES
(use
a #define OR make it an int constant) - set to
32, DEFAULT
(type Link) -
set to 0, INIT
(type Element)
set to 0, and NULLVAL
(type Link)
set to -1.
- Define a LinkedList
class prototype that contains the following private data members:
- a struct called Node
containing
members data
(of
type Element)
and next
(of type Link),
and a constructor that sets data to INIT and next to NULLVAL.
- an array of Node
called nodes
with capacity NUMNODES.
It will be used to model both
our available memory and our list.
- an int
called numFree
(i.e., the number of nodes available in the nodes array) and another int called numInList
(i.e., the number of nodes in the list).
- a Link called free (whose
value will be the
index of the first available unused node in memory, i.e., the free-nodes list).
- a Link
called first
(whose value will be
the index of the first node in the list).
- Write the prototypes for the following member functions:
- A LinkedList
default constructor.
- Predicate functions isEmpty
(returns bool)
and isMember
(takes in type Element and
returns bool).
- Accessor functions getNumFree
and getNumInList
(both return int).
- Mutator functions insert and remove
(both take in type Element).
- I/O functions display
(takes in type ostream)
and read
(takes in type istream).
- Private helper functions allocate
(returns type Link),
deallocate (takes in type Link), findPreviousNode
(takes in type Element,
returns type Link),
and search
(takes in type Element,
returns type Link).
- Write the prototype for the following non-member functions:
- Overloaded output (<<, takes in types ostream and
LinkedList,
returns type ostream)
and
input (>>, takes in types istream and
LinkedList,
returns type istream)
operators.
- Note: think carefully about whether the parameters and
return types of the above functions should be passed by value or passed
by reference. Discuss and specify during lab.
- Develop file LinkedList.cpp
as follows:
- Implement the constructor. It must initialize numFree to the number of nodes in the nodes
array, numInList
to INIT, first
to NULLVAL
(because
our
list is empty to start), free
to DEFAULT
(so it 'points' to the first available node in the node
array) and the next field
of
each node in the nodes
array to 'point' to the next node in the nodes
array. The next field
in the last position of
the nodes
array must be set
to NULLVAL
(because there are no available nodes after it). See
p. 306 for an illustration.
- Draw a picture depicting the nodes
array after initialization along with first
and free
(see the pictures on
pp. 305-308).
- Implement the getNumFree
function that returns the value of numFree
(i.e., the number of available nodes).
- Implement the getNumInList
function that returns the value of numInList
(i.e., the number of nodes on the list).
- Implement the isEmpty
function. It should return true
when the value of first is
equal to NULLVAL,
and false
otherwise.
- Implement the findPreviousNode
function. Given an element (i.e., to insert or delete), its
purpose is to find the location of the node already on the list (if
any) that should precede the given element in the
list. If there is none, the function should return NULLVAL.
- Implement the search
function. Given an element, its purpose is to find the location
of the node containing the given element on the list, if any. If
there is none, the function should return NULLVAL.
- Implement the allocate
function. It should return the location of the first free
node (i.e., free),
adjust the values of numFree and numInList,
and update free
to
point to the new first free node.
(See bottom of p.
306).
- Implement the deallocate
function. Given the location of a node to delete, it should set
the next
field of the deleted node to
free,
adjust the values of numFreenumFree and numInList,
and set free
to the
location of the deleted node.
(See bottom of p.307 and top
of 308).
- Implement the isMember
function. Given an element, it should return true if
that element is a member of the list, and false
otherwise.
- Implement the insert
function. Given an element, it should allocate a new node, set the data
field
of this node to the value of the element, then find and insert the node
into the proper point in the list.
- Implement the remove
function. It should find and delete the node from the list (if it
is in the list),
and deallocate
the node.
- Implement the display
function. It should display all the data members of the list.
- Implement the read
function. It should read in a series of
elements into this list.
- Implement the overloaded output operator (Same pattern as we've
seen).
- Implement the overloaded input operator (Same pattern as above,
but with istream
instead of ostream).
- Write a client program that tests your program by performing the
following:
- Create a list called list1.
- Check to see if the list isEmpty.
- Insert the following values into the list: 20, 50, 30, 10, 70.
- Check to see if the list isEmpty.
- Display the list.
- Call isMember
to check if the following values are in the list: 10,
25, 50, 70.
- Remove the following values from the list: 30, 20, 70.
- Check to see if the list isEmpty.
- Display the list.
- Add the following values to the list: 80, 0, 35.
- Display the list.
- Remove the following values from the list: 40, 10.
- Display the list.
- Remove the remaining values from the list.
- Check to see if the list isEmpty.
- Declare a new list, list2.
- Enter the values on the keyboard from step 3 above, and read them
into list2.
- Display the list.
- Draw a picture depicting the lists and their nodes
array (along with first and free) for
each of the above steps.
Submission: FTP all source files to your bigblackbox FTP account. Due dates and times as usual.
Last updated: 2/18/07 - RMW