Linked Lists
Array-Based List
Pointers
Pointer Example
 
 
 
 
 
 

Pointers (contd.)

Another Pointer Example
int* p;
int* q;
int x;

p = &x;
*p = 6;
p = new int;
*p = 7;
q = p;
q = new int;
*q = 8;
p = NULL; // Some programmers prefer 0.
delete q;

Pointer Facts
Memory Leak
Pointer Usage
int* p;
int* q;
int x;

p = &x;
q = p;
delete p; // Where does q point?

More Pointer Examples
typedef int* IntPtr;
IntPtr p; // Another way to declare
int x = 0;

*p = 5; // invalid. why?
p = &x;
*p = *p + 1; // x is now 1.
delete p; // invalid. why?
p = new int;
delete p;
*p = 5; // invalid. Why?

Dynamic Array Allocation
int* p;

p = new int[10]; // p is array now.
p[0] = 4; p[1] = 7;
delete [] p;

Pointer-Based Linked List
Linked List Picture
 
 
 
 
 

Node Structure

typedef int ListItem;
struct ListNode; // defined later.
typedef ListNode* ListNodePtr;

struct ListNode
{

ListItem item;
ListNodePtr next;
};

ListNodePtr head;

List Creation
ListNodePtr head = NULL;

head = new ListNode;
head->item = 7;
head->next = NULL; // one item list

ListNodePtr temp = new ListNode;
temp->item = 8;
temp->next = NULL;
head->next = temp; //2 item list.

List Analysis
Displaying a List
// pseudocode
curptr <- first node in list.
while (curptr is not NULL)
{ display data field in current node.
set curptr to next field of current node.
}
Display List in C++
// Display the data in a linked
// list pointed to by head.
// loop invariant: cur points to
// the next node to be displayed.

ListNodePtr cur;

for (cur = head; cur != NULL; cur = cur->next)
{

cout << cur->item << endl; }
Deleting a node in a list
Deleting an interior node
 
 
 
 
 

Deleting the first node
 
 
 
 
 

Deletion Code

// First find prev and cur.
if (prev == NULL)
{ head = cur->next;
delete cur;
}
else
{ prev->next = cur->next;
delete cur;
}
 
Inserting at front
 
 
 
 

Inserting in middle
 
 
 
 

Insertion Code

// Insert before cur, after prev.
// cur can be NULL (Inserting at end).
newPtr = new ListNode;
newPtr->item = newItem;
newPtr->next = cur;
if (prev == NULL)
{ head = newPtr; }
else
{ prev->next = newPtr; }
Insertion Code (Method 2)
// First find prev and cur.
// Note that prev should point to the
// pointer to be changed.
// e.g. prev = &cur->next;
// cur = cur->next;
newPtr = new ListNode;

// You should check for newPtr == NULL.
newPtr->item = newItem;
newPtr->next = cur;
*prev = newPtr;

Determining Prev and Cur
// An example of code with fault.
prev = NULL;
cur = head;
while (newValue > cur->item)
{ prev = cur;
cur = cur->next;
}

// What happens if cur becomes NULL at some point?

Change to (cur != NULL && newValue > cur->item).

More on Prev & Cur
Another Example
prev = NULL;
cur = head;
for (i = 1; i < pos && cur; i++)
{ prev = cur;
cur = cur->next;
}
if (i != pos)
{ // List is shorter. Handle this case. }
Shallow and Deep Copy
Array vs. pointer based lists
Saving a List Using a File
Saving a List (Code)
// Client Program to save the list
void SaveList(const List& list, const string& fileName)
{ ofstream outFile(fileName.c_str());
ListItem item;
unsigned int pos;
bool success;

for (pos = 1; pos <= list.Length(); pos++)
{

item = list.Retrieve(pos, item, success);
outFile << item << endl;
}
outFile.close();
}
Reading a List from a file
void ReadList(List& list, const string& fileName)
{ ifstream inFile(fileName.c_str());
ListItem item;
bool success;
unsigned int pos = 1;
while (inFile >> item)
{ list.Insert(pos++, item, success); }
list.close();
}
Saving a List (part of ADT)
void List::Save(const string& fileName) const
{ ofstream outFile(fileName.c_str());
ListItem item;
ListNodePtr cur;

for (cur = head; cur != NULL; cur = cur->next)
{

outFile << cur->item << endl; }

outFile.close();

}
Passing a List to a function
Objects as list data
Variations on Linked List
Doubly Linked List
Closer Look at C++
Sharing Dynamic Data
Object Assignment
List firstList; bool success;
firstList.Insert(1,5, success);
firstList.Insert(1,6, success);

List secondList(firstList); // copy const
List thirdList; // Default constructor

thirdList.Insert(1,3,success);
thirdList.Insert(1,6,success);
thirdList = firstList; // Needs operator=
  // Need to cleanup thirdList first.

Operator=
List& List::operator=(const List& rhs)
{ if (this == &rhs)
{ return (*this); }
Destroy(); // destroy lhs list.
Copy(rhs); // make lhs just like rhs.
return (*this);
}

More later!!