Lecture 4

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 13

Lists

CS122 Algorithms and Data Structures


A list is a varying-length, linear collection of
homogeneous elements.
Linear means each list element (except the
first) has a unique predecessor, and each
element (except the last) has a unique
MW 11:00 am - 12:15 pm, MSEC 101 successor
Instructor: Xiao Qin In a linear structure, components can only
Lecture 4: Linked Lists be accessed sequentially one after the
other

Lists (cont.) Lists as ADTs


Domain
It normally has two "special" named – A collection elements of the same type
elements called head and tail. They – An implicit list cursor in the range 1 through n+1where n
is the current length of the list.
point to the first and last element of the Operations
list. – create(): create a new list. Should be done using
constructors
– Boolean IsEmpty() & Boolean IsFull(): returns
true if the list is empty and full respectively
– void InsertBeginning(v) & void
InsertEnd(v): Insert the value v either in the end or
the beginning of the list
– void Delete(): item at list cursor deleted
– print(): Print the whole list

More List Operations Array-based class List


Operations
– insertAfter(v, anotherV): insert the value v
after the first occurrence of anotherV. IsEmpty
– insertBefore(v, anotherV): Insert the value v IsFull Private data:
before the first occurrence of anotherV.
Length length
– search(v): search for the first occurrence of v in the
list and return its position. Could be used to help the Insert data [0]
implementation of several other operations [1]
– deleteAll(v): Delete all occurrences of v in the list Delete [2]

– reset(): List cursor is at front of list.


IsPresent [MAX_LENGTH-1]
We can assume that private data in a list includes
the lists itself (using an array or linked list), the Print
head, the tail and the size of the list SortedList
6

1
// ARRAY-BASED LIST ( list.h )
const int MAX_LENGTH = 50 ;
typedef int ItemType ;
How to Implement a List
class SortedList
{
public : // public member functions
use a built-in array stored in contiguous memory
SortedList ( ) ; // constructor locations, implementing operations Insert and
bool IsEmpty ( ) const ;
bool IsFull ( ) const ;
Delete by moving list items around in the array,
int Length ( ) const ; // returns length of list as needed
void Insert ( ItemType item ) ;
void Delete ( ItemType item ) ;
bool IsPresent( ItemType item ) const ;
use a linked list (to avoid excessive data
void Print ( ) ; movement from insertions and deletions) not
necessarily stored in contiguous memory
private : // private data members
locations
int length ; // number of values currently stored
ItemType data[MAX_LENGTH] ;
void BinSearch ( ItemType item, bool& found, int& position ) const ;
}; 7

List Implementation via Arrays List Implementation via Arrays


create() insertEnd(40)
00 11 22 33 44 55 66 77

00 11 22 33 44 55 66 77

12
12 33 33
33 77 22

MAX_SIZE
MAX_SIZE == 88
size
size == 00
head
head == -1
-1 Tail
tail
tail == 00
vv
40
40

List Implementation via Arrays List Implementation via Arrays


insertEnd(40) insertBeginning(22)

00 11 22 33 44 55 66 77 00 11 22 33 44 55 66 77

12
12 33 33
33 77 22 40
40 12
12 33 33
33 77 22 40
40

vv
22
22
if
if list
list is
is not
not full
full Tail tail
list[tail]
list[tail] == vv
tail++
tail++
size++
size++

2
List Implementation Via Arrays List Implementation via Arrays
insertBeginning(22) insertBeginning(22)

00 11 22 33 44 55 66 77 00 11 22 33 44 55 66 77

12
12 33 33
33 77 22 40
40 40
40 12
12 33 33
33 77 22 22 40
40

vv vv
22
22 22
22

List Implementation via Arrays List Implementation via Arrays


insertBeginning(22) insertBeginning(22)

00 11 22 33 44 55 66 77 00 11 22 33 44 55 66 77

12
12 33 33
33 77 77 22 40
40 12
12 33 33
33 33
33 77 22 40
40

vv vv
22
22 22
22

List Implementation via Arrays List Implementation via Arrays


insertBeginning(22) insertBeginning(22)

00 11 22 33 44 55 66 77 00 11 22 33 44 55 66 77

12
12 33 33 33
33 77 22 40
40 12
12 12
12 33 33
33 77 22 40
40

vv vv
22
22 22
22

3
List Implementation via Arrays List Implementation via Arrays
insertBeginning(22) delete(33)

00 11 22 33 44 55 66 77 00 11 22 33 44 55 66 77

22
22 12
12 33 33
33 77 22 40
40 22
22 12
12 33 33
33 77 22 40
40

if
if list
list is
is not
not full
full
for
for i=(tail-1)
i=(tail-1) to
to 00 tail tail
list[i+1]
list[i+1] == list[i]
list[i]
list[0] =
list[0] = vv
tail++
tail++
size++
size++

List Implementation via Arrays List Implementation via Arrays


delete(33) delete(33)

00 11 22 33 44 55 66 77 00 11 22 33 44 55 66 77

22
22 12
12 33 33
33 77 22 40
40 22
22 12
12 33 33
33 77 22 40
40

is
is this
this 33?
33?
is
is this
this 33?
33?
tail

List Implementation via Arrays List Implementation via Arrays


delete(33) delete(33)

00 11 22 33 44 55 66 77 00 11 22 33 44 55 66 77

22
22 12
12 33 33
33 77 22 40
40 22
22 12
12 33 33
33 77 22 40
40

is
is this
this 33?
33? is
is this
this 33?
33?

4
List Implementation via Arrays List Implementation via Arrays
delete(33) delete(33)

00 11 22 33 44 55 66 77 00 11 22 33 44 55 66 77

22
22 12
12 33 77 77 22 40
40 22
22 12
12 33 77 22 22 40
40

List Implementation via Arrays List Implementation via Arrays


delete(33) delete(33)

00 11 22 33 44 55 66 77 00 11 22 33 44 55 66 77

22
22 12
12 33 77 22 40
40 40
40 22
22 12
12 33 77 22 40
40

if
if list
list is
is not
not empty
empty
ii == head+1;
head+1;
while
while (v(v !=
!= list[i]
list[i] and
and ii << tail)
tail)
i++
i++
if
if (i
(i << tail)
tail) tail’ tail
for
for j=i
j=i to
to (tail-2)
(tail-2)
list[i]
list[i] == list[i+1]
list[i+1]
list[tail-1]
list[tail-1] == null;
null;
size--
size--
tail--
tail--

How to Implement a List Linked Lists vs. Arrays


use a built-in array stored in contiguous memory Lists differ from arrays because they don't have a
locations, implementing operations Insert and fixed size but like arrays can only store elements
Delete by moving list items around in the array, of the same type
as needed
Main advantage over arrays is easy insertion and
use a linked list (to avoid excessive data deletion of nodes
movement from insertions and deletions) not A well defined list may be the basis for the
necessarily stored in contiguous memory implementation of several other data structures,
locations such as queues, stacks, trees and graphs.

5
Self-referential data types A Linked List
a linked list is a list in which the order of the
class Node { components is determined by an explicit link
private Object info; // the “info” member in each node
the nodes are structs--each node contains a
private Node next; // the “link” component member and also a link member that
} gives the location of the next node in the list
an external pointer (or head pointer) points to the
first node in the list
data next
head 10 8 50

Nodes can be located anywhere in


memory Declarations for a Linked List
// Type DECLARATIONS
struct NodeType {
the link member holds the memory address of the
int info;
next node in the list
NodeType* next;
Memory address
}

head 3000 5000 2000 // Variable DECLARATIONS


NodeType* head;
3000 10 5000 8 2000 50 NULL
NodeType* ptr;

8 6000
34
info next

Member Selection Traversing a Linked List


ptr ptr 8 6000 ptr
info next 3000 5000 2000
head 3000 10 5000 8 2000 50 NULL

*ptr ptr 8 6000


//PRE: head points to a linked list
info next node *ptr ;

ptr = head ;
while (ptr != NULL) {
(*ptr).info ptr 8 6000 cout << ptr->info ;
info next // Or, do something else with
ptr->info ptr = ptr->next ;
}
35

6
Traversing a Linked List Traversing a Linked List
ptr 3000 ptr 3000

3000 5000 2000 3000 5000 2000


head 3000 10 5000 8 2000 50 NULL head 3000 10 5000 8 2000 50 NULL

//PRE: head points to a linked list //PRE: head points to a linked list
node *ptr ; node *ptr ;

ptr = head ; ptr = head ;


while (ptr != NULL) { while (ptr != NULL) {
cout << ptr->info ; cout << ptr->info ;
// Or, do something else with // Or, do something else with
ptr = ptr->next ; ptr = ptr->next ;
} }

Traversing a Linked List Traversing a Linked List


ptr 3000 ptr 5000

3000 5000 2000 3000 5000 2000


head 3000 10 5000 8 2000 50 NULL head 3000 10 5000 8 2000 50 NULL

//PRE: head points to a linked list //PRE: head points to a linked list
node *ptr ; node *ptr ;

ptr = head ; ptr = head ;


while (ptr != NULL) { while (ptr != NULL) {
cout << ptr->info ; cout << ptr->info ;
// Or, do something else with // Or, do something else with
ptr = ptr->next ; ptr = ptr->next ;
} }

Traversing a Linked List Traversing a Linked List


ptr 5000 ptr 5000

3000 5000 2000 3000 5000 2000


head 3000 10 5000 8 2000 50 NULL head 3000 10 5000 8 2000 50 NULL

//PRE: head points to a linked list //PRE: head points to a linked list
node *ptr ; node *ptr ;

ptr = head ; ptr = head ;


while (ptr != NULL) { while (ptr != NULL) {
cout << ptr->info ; cout << ptr->info ;
// Or, do something else with // Or, do something else with
ptr = ptr->next ; ptr = ptr->next ;
} }

7
Traversing a Linked List Traversing a Linked List
ptr 2000 ptr 2000

3000 5000 2000 3000 5000 2000


head 3000 10 5000 8 2000 50 NULL head 3000 10 5000 8 2000 50 NULL

//PRE: head points to a linked list //PRE: head points to a linked list
node *ptr ; node *ptr ;

ptr = head ; ptr = head ;


while (ptr != NULL) { while (ptr != NULL) {
cout << ptr->info ; cout << ptr->info ;
// Or, do something else with // Or, do something else with
ptr = ptr->next ; ptr = ptr->next ;
} }

Traversing a Linked List Traversing a Linked List


2000 NULL
ptr ptr

3000 5000 2000 3000 5000 2000


head 3000 10 5000 8 2000 50 NULL head 3000 10 5000 8 2000 50 NULL

//PRE: head points to a linked list //PRE: head points to a linked list
node *ptr ; node *ptr ;

ptr = head ; ptr = head ;


while (ptr != NULL) { while (ptr != NULL) {
cout << ptr->info ; cout << ptr->info ;
// Or, do something else with // Or, do something else with
ptr = ptr->next ; ptr = ptr->next ;
} }

Traversing a Linked List Using Operator new


NULL
ptr
If memory is available in an area called the free
store (or heap), operator new allocates the
3000 5000 2000
requested object, and returns a pointer to the
head 3000 10 5000 8 2000 50 NULL
memory allocated.
//PRE: head points to a linked list
node *ptr ; The dynamically allocated object exists until the
ptr = head ; delete operator destroys it.
while (ptr != NULL) {
cout << ptr->info ;
// Or, do something else with
ptr = ptr->next ;
}
48

8
Inserting a Node at the Front of Inserting a Node at the Front of
a List a List
item 6 item 6

int item = 6; int item = 6;


Node *location; Node *location;
location = new NodeType; location = new NodeType;
location->info = item; location->info = item;
location->next = head; location->next = head;
head = location; head = location;

head 5 8 3 head 5 8 3

49 location 50

Inserting a Node at the Front of Inserting a Node at the Front of


a List a List
item 6 item 6

int item = 6; int item = 6;


Node *location; Node *location;
location = new NodeType; location = new NodeType;
location->info = item; location->info = item;
location->next = head; location->next = head;
head = location; head = location;

head 5 8 3 head 5 8 3

location 51 location 6 52

Inserting a Node at the Front of Inserting a Node at the Front of


a List a List
item 6 item 6

int item = 6; int item = 6;


Node *location; Node *location;
location = new NodeType; location = new NodeType;
location->info = item; location->info = item;
location->next = head; location->next = head;
head = location; head = location;

head 5 8 3 head 5 8 3

location 6 53 location 6 54

9
Using Operator delete Deleting the First Node from the List
item

The object currently pointed to by the Node *tempPtr;


pointer is deallocated, and the pointer is
item = head->info;
considered undefined. The object’s
tempPtr = head;
memory is returned to the free store.
head = head->next;
delete tempPtr;

head 6 5 8 3

55 tempPtr 56

Deleting the First Node from the List Deleting the First Node from the List
item 6 item 6
Node *tempPtr; Node *tempPtr;

item = head->info; item = head->info;


tempPtr = head; tempPtr = head;
head = head->next; head = head->next;
delete tempPtr; delete tempPtr;

head 6 5 8 3 head 6 5 8 3

tempPtr 57 tempPtr 58

Deleting the First Node from the List Deleting the First Node from the List
item 6 item 6
Node *tempPtr; Node *tempPtr;

item = head->info; item = head->info;


tempPtr = head; tempPtr = head;
head = head->next; head = head->next;
delete tempPtr; delete tempPtr;

head 6 5 8 3 head 5 8 3

tempPtr 59 tempPtr 60

10
// SPECIFICATION FILE person.h
class PersonList
#include “bool.h”
. . .

struct PersonRec
PersonList {
Private M a x \0 E d \0 char* name ; // Pointer to person’s name
~PersonList int age ; // Person’s age
data:
};
IsEmpty
head 13 21
CurrentRec struct PersonNode
{
currPtr
InsertAfter char* name ; // Pointer to person’s name
int age ; // Person’s age
Advance PersonNode *next ; // Pointer to next node in list
};

Delete 61 62

// SPECIFICATION FILE continued person.h // LINKED LIST IMPLEMENTATION FILE ( person.cpp )


class PersonList #include “person.h”
{ . . .
public : // LINKED LIST IMPLEMENTATION
PersonList ( ) ; PersonList::PersonList ( ) // constructor
~PersonList ( ) ; // PRE: None.
Boolean IsEmpty ( ) const ; // POST: Empty list created && EndOfList( ).
Boolean IsFull ( ) const ; {
void Reset ( ) ; head = NULL;
Boolean EndOfList ( ) const ; currPtr = NULL;
void InsertAfter ( PersonRec someRec ) ; }
void InsertBefore ( PersonRec someRec ) ;
void Advance ( );
Boolean PersonList::IsEmpty ( ) const
void Delete ( ) ;
// POST: FCTVAL == ( list is empty )
PersonRec CurrentRec ( ) const ;
{
private : return ( head == NULL ) ;
PersonNode *head ; }
PersonNode *currPtr ;
}; 63 64

Boolean PersonList::EndOfList ( ) const


// IMPLEMENTATION CONTINUED ( person.cpp ) // POST: FCTVAL == ( list cursor is beyond end of list )
{
void PersonList::Reset ( ) return ( currPtr == NULL ) ;
// PRE: NOT IsEmpty ( ) }
// POST: List cursor is at front of list
{ void PersonList::Advance ( )
// PRE: NOT IsEmpty( ) && NOT EndOfList( )
currPtr = head ;
// POST: List cursor has advanced to next record
}
{
currPtr = currPtr->next ;
PersonRec PersonList::CurrentRec ( ) const }
// PRE: NOT IsEmpty ( ) && NOT EndOfList ( )
// POST: FCTVAL == record at list cursor PersonList::~PersonList ( ) // destructor
{ // POST: List destroyed
PersonRec rec ; {
currPtr = head ;
rec.name = currPtr->name ; while ( ! EndOfList ( ) )
rec.age = currPtr->age ; Delete ( ) ;
return rec ; }
} 65 66

11
Ted \0
void PersonList::InsertAfter ( PersonRec someRec )
// PRE: Assigned (someRec) && NOT IsEmpty( ) Insert 16 into the PersonList
// && NOT IsFull ( ) && NOT EndOfList ( )
// POST: someRec inserted after list cursor
// && This new node has become the current record
{ PersonList
// obtain and fill a node Private M a x \0 E d \0
~PersonList
PersonNode *ptr = new PersonNode ; data:
IsEmpty
ptr->name = new char [ strlen ( someRec.name) + 1 ] ; head 13 21
strcpy( ptr->name, someRec.name ); CurrentRec
ptr->age = someRec.age ; currPtr
ptr->next = currPtr->next ; InsertAfter
currPtr->next = ptr ; Advance
currPtr = ptr ;
}
Delete
67

Ted \0 Ted \0
PersonNode *ptr = new PersonNode ;
Inserting 16 into the PersonList 16

someRec someRec
after list cursor
ptr

Private data: M a x \0 E d \0 Private data: M a x \0 E d \0

head 13 21 head 13 21

currPtr currPtr

50 70

Ted \0 Ted \0

16
ptr->name = new char[4] ; 16
strcpy( ptr->name, someRec.name ) ;
someRec someRec
Ted \0

ptr ptr

Private data: M a x \0 E d \0 Private data: M a x \0 E d \0

head 13 21 head 13 21

currPtr currPtr

71 72

12
Ted \0 Ted \0
ptr->age = someRec.age ; ptr->next = currPtr->next ;
16 16

someRec someRec
Ted \0 Ted \0

ptr 16 ptr 16

Private data: M a x \0 E d \0 Private data: M a x \0 E d \0

head 13 21 head 13 21

currPtr currPtr

73 74

Ted \0 Ted \0

16
currPtr->next = ptr ; 16 currPtr = ptr ;
someRec someRec
Ted \0

ptr ptr “Ted” 16

Private data: M a x \0 E d \0 Private data: M a x \0 E d \0

head 13 21 head 13 21

currPtr currPtr

75 76

13

You might also like