You are on page 1of 11

This material is provided to the professors and students using Data Structures: A Pseudocode Approach Using C++.

All reprints in any form must cite this copyright.


Copyright(c) 2001 by Brooks/Cole
A division of Thomson Learning

Chapter 3 Linear Lists


Exercises
1.

3.

pList is a unique pointer that is used to keep track of the head (first node) of the list. Executing the statement
pList = pList->link modifies pList to no longer point to the first node of the list. This may have devastating
effects for the entire program. This fact justifies the need for the two walking pointers, pPre and pLoc, which
keep track of the predecessor and the current nodes without altering the head pointer.
pPre->link = pCur->link
recycle (pCur)

5.

1
2
3
4

7.

list1 no longer points to the head of the first list, rather it points to the head of the second list in the figure. The
first list is lost forever.
This will create a circularly linked list.

9.

allocate (pNew)
...
pNew->link = pPre->link (pPre points to dummy node)
pPre->link = pNew

Problems
11.

algorithm minimum (val pList <head pointer>)


This algorithm accepts a link list, traverses it and returns the data in
the node with the minimum key value
Pre pList is a valid pointer to the head of the list
Post the data with minimum key value has been
returned or in case of an empty list, an invalid
data value is returned
1 min = invalid data value
2 if (pList not null)
1 min
= pList->data
2 pWalk = pList->link
3 loop (pWalk not NULL)
1 if (pWalk->data < min)
1 min = pWalk->data
2 end if
3 pWalk = pWalk->link
4 end loop
3 end if
4 return (min)
end minimum

13.

algorithm delAfterNegative (ref pList <head pointer>)


This algorithm traverses a linked list and deletes all nodes that are
after a node with a negative key
Pre List is a pointer to the head of a linked list
Post returns false if empty list or true otherwise
1 pWalk = pList
2 loop (pWalk not null)
1 if (pWalk->key < 0 AND pWalk->link not null)
Page 3.1

1 deleteNode(pList, pWalk, pWalk->link, dataOut)


2 end if
3 pWalk = pWalk->link
3 end loop
4 return (pList not equal null)
end delAfterNegative
15.

algorithm appendAndCount
This algorithm is basically a modified version of the Algorithm 3-16,
appendTwoLists and the build and the append algorithms are unmodified.
The whole algorithm creates two linked lists, appends the second to the
first, and displays the count of nodes in the appended list.
Pre nothing
Post creates and appends the lists,
prints final list and displays total count
1 build (pList1, file1)
2 build (pList2, file2)
3 append (pList1, pList2)
list2 is appended after list1 and list count updated
4 printList (pList1)
5 print(pList1->count)
6 return
end appendAndCount

17.

/* This program creates a two dimensional linked list.


The nodes in the first column contain only two
pointers; the left pointer points to the next row
and the right pointer points to the data in the row.
*/
#include <iostream.h>
#include <iomanip.h>
#include <stdlib.h>
#include <bool.h>
// Global Declarations
#define KEY_TYPE int
struct DATA
{
KEY_TYPE key;
};
struct NODE
{
DATA data;
NODE *link;
};
#define POINTER NODE *
struct TABLE
{
TABLE *link;
NODE *row;
};
#define TPOINTER TABLE *

Page 3.2

// Prototype Declarations
void build_table (TPOINTER
void print_table (TPOINTER
void build_list
(POINTER
void add_node
(POINTER
bool search_list (POINTER
POINTER
POINTER
KEY_TYPE
void delete_table (TPOINTER
int main (void)
{
// Local Definitions
TPOINTER t_list =

&t_list);
t_list);
&p_list, int row);
&p_list, KEY_TYPE key);
p_list,
&p_pre,
&p_cur,
target);
&t_list);

NULL;

// Statements
build_table (t_list);
print_table (t_list);
delete_table (t_list);
}

return 0;
// main

/* =================== build_table ===================


This function builds a two dimensional linked list.
Pre
Table pointer passed by reference
Post
Table built and address stored in t_list
*/
void build_table (TPOINTER & t_list)
{
// Local Definitions
TPOINTER t_new;
TPOINTER t_cur = t_list;
int i;
int rows;
// Statements
cout << "\nHow many rows in the table? :
cin >> rows;

";

for (i = 0 ; i < rows ; i++)


{
t_new = new TABLE;
if (!t_new)
{
cerr << "\a\nOverflow in build_table\n";
exit (100);
} // if overflow
t_new -> link = NULL;
t_new -> row
= NULL;
if (t_list == NULL)
t_list = t_cur = t_new;
else
{
t_cur -> link = t_new;

Page 3.3

t_cur
} // else

t_new;

build_list (t_cur -> row, i);


} // for
return;
} // build_table
/* =================== build_list ====================
This function builds a linked list.
Pre
Pointer to an empty linked list.
row number being built
Post
List is built.
*/
void build_list (POINTER & p_list, int row)
{
// Local Definitions
KEY_TYPE key;
bool quit = false;
// Statements
if (p_list != NULL)
{
cerr << "\a\nERROR: Null pointer in build_list";
exit (200);
} // if null pointer
cout << "Enter list of numbers for row " << row
<< " of table (zero to stop): \n";
while (!quit)
{
cin >> key;
if (key == 0)
quit = true;
else
add_node (p_list, key);
} // while
}

return;
// build_list

/* =================== print_table ===================


Traverse and print a two dimensional linked list
Pre t_list is valid two dimensional linked list.
Post List has been printed.
*/
void print_table (TPOINTER t_list)
{
// Local Definitions
TPOINTER t_walker;
POINTER p_walker;
int row;
// Statements
t_walker = t_list;
cout << "\nList contains :\n";
row = 0;

Page 3.4

while (t_walker)
{
cout << " Row " << setw(4) << row << " :
p_walker = t_walker -> row;

";

while (p_walker)
{
cout << setw (5) << p_walker -> data.key;
p_walker = p_walker -> link;
} // while p_walker
cout << endl;
t_walker = t_walker -> link;
row++;
} // while t_walker
cout << endl;
}

return;
// print_table

/* ==================== add_node =====================


This function inserts a node into a linked list.
Pre p_list is alias to passed list
key is key of node to be inserted in list.
Post node inserted
*/
void add_node (POINTER &p_list, KEY_TYPE key)
{
// Local Definitions
POINTER p_new;
POINTER p_pre;
POINTER p_cur;
// Statements
p_new = new NODE;
if (!p_new)
{
cerr << "\a\n**Overflow in add_node.\n";
exit (300);
} // if !p_new
p_new -> data.key
p_new -> link

=
=

key;
NULL;

if (search_list (p_list, p_pre, p_cur, key))


cout << "\a\n**"
<< key << " already in list\n";
else
{
if (p_pre == NULL)
{
// adding before first node or to empty list
p_new -> link = p_list;
p_list
= p_new;
} // if p_pre null
else
{

Page 3.5

// adding in middle or at end


p_new -> link = p_pre -> link;
p_pre -> link = p_new;
} // else
} // else not in list
}

return;
// add_node

/* =================== search_list ===================


Given key value, finds the location of a node.
Pre p_list is a pointer to a head node.
p_pre is pre node alias
p_cur is current node alias
target is the key being sought.
Post p_cur points to first node with >= key
or null if target > key of last node
p_pre points to largest node < key
or null if target <= key of first node.
Returns true if found, false if not found.
*/
bool search_list (POINTER p_list,
POINTER &p_pre,
POINTER &p_cur,
KEY_TYPE target)
{
// Local Definitions
bool found;
// Statements
p_pre = NULL;
p_cur = p_list;
while (p_cur && target > p_cur -> data.key)
{
p_pre = p_cur;
p_cur = p_cur -> link;
} // while
if (p_cur && p_cur -> data.key
found = true;
else
found = false;

==

target)

return found;
}

// Search_list

/* ================== delete_table ===================


This function recycles the memory used by a table
(two dimensional linked list).
Pre t_list is alias to table
Post memory used by t_list has been recycled.
*/
void delete_table (TPOINTER & t_list)
{
// Local Definitions

Page 3.6

POINTER
POINTER
TPOINTER
TPOINTER

p_walker;
p_del;
t_walker;
t_del;

// Statements
t_walker = t_list;
while (t_walker)
{
p_walker = t_walker -> row;
while (p_walker)
{
p_del
= p_walker;
p_walker = p_walker -> link;
delete (p_del);
} // while p_walker

t_del
= t_walker;
t_walker = t_walker -> link
delete (t_del);
} // while t_walker
t_list = NULL;
return;
// delete_table

19.

algorithm deleteNode (ref pList


<head pointer>,
val pPre
<node pointer>,
val pLoc
<node pointer>,
ref dataOut <dataType>)
Deletes data from a linked list with a dummy node and returns it to
caller.
Pre pList is a valid pointer to a list
pPre is a pointer to data's predecessor
pLoc is a pointer to node to be deleted
dataOut variable for deleted data
Post data have been deleted and returned
1 dataOut
= pLoc->data
2 pPre->link
= pLoc->link
3 recycle(pLoc)
4 pList->count = pList->count - 1
end deleteNode

21.

algorithm lastNode (val pList <head pointer>)


This algorithm returns a pointer to the last node
Pre pList is a pointer to a valid list
Post the pointer to the last node is returned
1 walk = pList->head
2 if (walk not null)
1 loop (walk->link not NULL)
1 walk = walk->link
2 end loop
3 end if
4 return walk
end lastNode

23.

algorithm appendToItself (val pList <head pointer>)


This algorithm appends a linked list to itself.
Pre the list has been created
Post the list is appended to itself

Page 3.7

if (pList->count is zero)
1 print (Error: Empty List can't be appended)
2 else
1 pred = pList->head
2 loop (pred->link not NULL)
1 pred = pred->link
3 end loop
4 pEnd = pred
5 walk = pList->head
6 loop(walk not equal pEnd)
1 success = insertNode (pList, pred, walk->data)
2 if (not success)
1 print (Overflow error in appendToItself)
2 abort program
3 end if
4 pred = pred->link
5 walk = walk->link
7 end loop
8 success = insertNode(pList, pred, walk->data)
9 if (not success)
1 print (Overflow error in appendToItself)
2 abort program
10 end if
3 end if
4 return
end appendToItself
25.

/* This program creates two linked lists, prints them,


appends the second list to the end of the first, and
prints the appended list. For simplicity, the Item
structure will contain only a 'key' that will be
used to hold the integer data.
*/
#include <fstream.h>
#include <iomanip.h>
#include <stdlib.h>
#include "listadt.h"
// Global Definitions
#define FILE_1 "file1.dat"
#define FILE_2 "file2.dat"
struct ITEM
{
int key;
};
// Prototype Declarations
void build
(List<ITEM,
void append
(List<ITEM,
List<ITEM,
void printList (List<ITEM,

int>
int>
int>
int>

&list, char *filename);


&list1,
&list2);
&list);

int main (void)


{
// Local Definitions
List<ITEM, int> list1;

Page 3.8

List<ITEM, int> list2;


// Statements
build
printList
build
printList

(list1 , FILE_1);
(list1);
(list2 , FILE_2);
(list2);

append (list1 , list2);


printList (list1);
}

return 0;
// main

/* ==================== build ====================


This function creates a linked list from file data.
Pre list is a valid list object
file must exist
Post list has been created from file data
*/
void build (List <ITEM, int> &list, char *filename)
{
// Local Definitions
ifstream fp;
ITEM
item;
// Statements
fp.open(filename, ios :: in);
if (!fp)
{
cerr << "\n\aCannot open " << filename << endl;
exit (100);
}
while (fp >> item.key)
list.addNode(item);
fp.close();
return;
} // build
/* ====================== append =====================
This function appends a second list to a first list
Pre both the lists are already been created
Post the lists are appended
*/
void append (List <ITEM, int> &list1,
List <ITEM, int> &list2)
{
// Local Definitions
ITEM item;
// Statements
list2.getNext (0, item);

Page 3.9

list1.addNode (item);

while (list2.getNext (1, item))


list1.addNode (item);
return;
// append

/* ==================== printList ====================


function prints a linked list of integers.
Pre list is a linked list object
Post list has been printed
*/
void printList (List <ITEM, int> &list)
{
// Local Definitions
int itemNo;
ITEM item;
// Statements
if (list.listCount() == 0)
cout << "\nNothing in list.\n\n";
else
{
cout << "\nContents of List:\n";
itemNo = 0;
list.getNext(0, item);
do
{
if (itemNo == 10)
{
cout << endl;
itemNo = 0;
} // if 10
cout << setw(5) << item.key;
itemNo++;
} while (list.getNext(1, item));
cout << "\nEnd of List\n\n";
} // else
}
27.

return;
// PrintList

algorithm merge

(val pList1 <TYPE, KTYPE>,


ref pList2 <TYPE, KTYPE>)
This algorithm merges two linked list in sequential
order and returns a List object containing the merged list.
Pre Both lists must exist
Post pointer to the final merged list is returned
1
2
3
4

List<TYPE, KTYPE> mergeList


Copy pList1 to tempList
walk = pList1.head
pPre = null
loop (walk not null)
1 mergeList._insert(pPre, walk->data)
2 pPre = walk
3 walk = walk->link

Page 3.10

This

end loop
Now merge pList2
6 walk = pList2.head
7 loop (walk not NULL)
1 found = mergeList._search (pPre, pLoc, walk->data.key)
2 if (found is true)
1 print (Duplicate data not merged,
pLoc->data.key)
3 else
1 mergeList._insert(pPre, walk->data)
4 end if
5 walk = walk->link
8 end loop
9 return mergeList
end merge

Page 3.11

You might also like