You are on page 1of 58

Chapter 4

Linked Lists(Part II)


•Equivalence Class
•Sparse Matrices
•Doubly Linked Lists
•Generalized Lists
•Virtual Functions & Dynamic Binding
•Heterogeneous Lists

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-1


Equivalence Relation
• A relation is a set of pair (x, y)
– where x and y are elements in a set, say S
• Three properties of an equivalence relation
– Reflexive: xx
– Symmetric: if x y, then y x
– Transitive: if x y and y z then x z
• Definition
– A relation over a set S, is said to be an equivalence
relation over S iff it is symmetric, reflexive, and
transitive over S.
– E.g., “equal to” (=) relationship is an equivalence
relation

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-2


Finding Equivalence Classes
• Input
– 04, 31, 610, 89, 74, 68, 35, 211, 110
• Output
– Three equivalence classes by applying the three
properties:
• {0, 2, 4, 7, 11}; {1, 3, 5}; {6, 8, 9, 10};
• Basic Algorithm
– (phase 1): equivalence pairs (i, j) are read in and stored
– (phase 2): find each equivalence class by transitive rule

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-3


Data Structure for Storing the
Equivalence Pairs
Equivalence pairs:
04,3 1,6 10,8 9,74, 68, 35,211,110
[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]

11 3 11 5 7 3 8 4 6 8 6 0

4 1 0 10 9 2

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-4


Finding Equivalence Class
Containing Node 0
Processing order:[0]→[11]→[4]→[7]→[2]
equivalence class containing 0: {11, 4, 7, 2}

[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]

11 3 11 5 7 3 8 4 6 8 6 0

4 1 0 10 9 2

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-5


Overall Equivalence Class
Computation
void equivalence()
{ read n; // read in number of objects
initialize seq[ ] to 0 and out[ ] to FALSE;
while more pairs // input pairs
{
read the next pair (i, j)
put j on the seq[i] list;
put i on the seq[j] list;
}
for (i=0;i<n;i++)
if(out[ i ]==FALSE) {
out[ i ]= TRUE;
output the equivalence class that contains object i;
}
} // end of equivalence

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-6


Data Structure in C++
enum Boolean{ FALSE,TRUE };
class ListNode{
friend void equivalence();
private:
int data
ListNode *link;
ListNode(int); // constructor
// ListNode(int=0, link=0);
};

typedef ListNode *ListNodePtr;


// so we can create an array of pointers using new
ListNode::ListNode(int d)
{
data = d;
link = 0;
}

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-7


void equivalence()
//input the equivalence pairs and output the equivalence classes
{ ifstream inFile("equiv.in",ios::in); //"equiv.in" is th input file
if(!inFile){
cerr<<"Cannot open input file"<< endl;
return;
}
}

int i, j, n;
inFile >> n; // read number of objects
// initialize seq and out
ListNodePtr *seq = new ListNodePtr[n];
Boolean *out = new Boolean[n];
for(i=0; i<n; i++){
seq[ i ] = 0;
out[ i ] = FALSE;
}
J.-J. Chen, EE NTUST April 13, 2023 Linked List II-8
do{ inFile>> i >> j; { // check end of file //phase 1:input equivalence pairs
ListNode *x = new ListNode(j); x->link=seq[i]; seq[i]=x; // add j to seq[i]
ListNode *y = new ListNode(i); y->link=seq[j]; seq[j]=y; // add i to seq[j]
} while(inFile.good());

04, 31, 610, 89, 74, 68, 35, 211,110


i j 0 4 11

j i y
x 11 0 0
x 0 0

- - 4
y
0 0 0

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-9


do{ inFile>> i >> j; { // check end of file //phase 1:input equivalence pairs
seq[i] = new ListNode( j, seq[i]); // add j to seq[i]
seq[j] = new ListNode( i, seq[j]); // add i to seq[j] A more simple way
} while(inFile.good()); to implement

04, 31, 610, 89, 74, 68, 35, 211,110


0 4 11
seq[i] seq[j]

j i y
x 11 0 0
x 0 0

- - 4
y
0 0 0

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-10


for(i=0;i<n;i++) //Phase 2: output equivalence classes
if(out[i]==FALSE) { // NEEDS TO BE OUTPUT
cout << endl <<"A new class:"<<i; out[i]= TRUE; There are two bugs in this
ListNode *x = seq[i]; ListNode *top = 0; // init stack program, please run and find
while(1) { // find rest of class and modify them.
while(x) { //process the list
j = x→data ; // free the space of nodes
if (out[j]==FALSE) { for(i=0;i<n;i++)
cout<<","<<j; while(seq[i]) {
out[j]=TRUE; ListNode *delnode=seq[i];
ListNode *y = x→link; seq[i] = delnode→link;
x→link = top; delete delnode;
top=x; x=y; }
} delete [ ] seq; delete [ ] out;
else x = x→link; }// end of equivalence
} // end of while(x)
if (!top) break;
else { x = seq[top→data]; top = top→link; // unstack }
} // end of while(1)
} // end of if(out[i]=FALSE)

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-11


Chapter 4
Linked Lists(Part II)
•Equivalence Class
•Sparse Matrices
•Doubly Linked Lists
•Generalized Lists
•Virtual Functions & Dynamic Binding
•Heterogeneous Lists

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-12


Sparse Matrix Representation
• Sequential Approach
– Nonzero terms was represented by sequential
structure
– Number of nonzero terms will vary after matrix
operations → destroy the sequential structure
– Suffer the same inadequacies as for polynomials
• Generalized List Approach
– Linked-list facilitate efficient representation of varying-
size structure
– Overcomes the shortcomings of sequential approach
with fixed address ordering

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-13


Dimensional Linked List

0 0 11 0 0 13 0 
12 0 0 0 0 0 14
 
 0 − 4 0 0 0 −8 0 
Field: head  
 0 0 0 0 0 0 0  Head of head nodes
→To distinguish
0 0 0 0 0 0 0 i, j denotes the dimension
between head nodes
  of the matrix
and nonzero terms  0 − 9 0 0 0 0 0 

down head right down head row col right f i j


Next Value aij

head node typical node Set up for aij

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-14


Sparse Matrix Example (1)
https://youtu.be/stjV64Vf0rQ

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-15


Sparse Matrix Example (2)
H H0 H1 H2 H3 H4
5 4 6

H0
0 0 2

H1
1 0 4 1 3 3

H2 Example sparse matrix


2 0 0 0
H3 4 0 0 3
3 0 8 3 3 1 
0 0 0 0
H4  
8 0 0 1
4 2 6
0 0 6 0

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-16


Class definition of Sparse Matrix (1)
struct Triple {int row, col, value;};
class Matrix; // forward declaration
down head right

class MatrixNode { Next


friend class Matrix; head node
friend istream& operator>>(istream&, Matrix&);
// for reading in a matrix
down head row col right
private:
MatrixNode *down , *right; Value
bool head; typical node
union { // anonymous (沒有名字的) union
MatrixNode *next;
Triple triple;
}; (prog.4.29)
MatrixNode(bool, Triple*); // constructor
}

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-17


Class definition of Sparse Matrix (2)

MatrixNode::MatrixNode(bool b, Triple *t) // constructor


{
head = b;
if (b) {right = down = this;} // row/column headnode
else triple = *t; // headnode for list of headnodes or element node
}

class Matrix{
friend istream& operator>>(istream&, Matrix&);
public:
~Matrix(); // destructor
private:
MatrixNode *headnode;
};

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-18


Read In a Sparse Matrix (1) 4 5 6
H H0 H1 H2 H3 H4

1 istream& operator>>(istream& is, Matrix& matrix) H0


0 0 2

H1

2 { // read in a matrix and setup its link representation H2


1 0 4 1 3 3

// An auxiliary array head is used Example sparse mat


2 0 0 0
H3 4 0 0 3

3 Triple s; H4
3 0 8 3 3 1
0

0 0 0

8 0 0 1
4 2 6
0 0
4 is >> s.row >> s.col >> s.value; // matrix dimensions
0 6

5 int p = max(s.row, s.col); s holds matrix dimension


6 // setup headnode of list of head nodes p = max{#rows, # cols}
7 matrix.headnode = new MatrixNode(false, &s);
8 if (p = = 0) { matrix.headnode → right = matrix.headnode; return is;}
9 // at least one row or column
10 MatrixNode **head = new MatrixNode* [p ]; // initialize head nodes
11 for (int i = 0; i < p; i++)
12 head[i] = new MatrixNode(true, 0);
13 int currentRow = 0;
14 MatrixNode *last = head[0]; // last node in current row

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-19


Read In a Sparse Matrix (2)
15 Triple *t=new Triple[s.value]; // modified by j.j.chen
for (i = 0; i < s.value; i++) { // input triples
Trick: head[i]→next is used
18 is >> t[i].row>>t[i].col>>t[i].value;
initially to keep track of the last
19 if (t[i].row > currentRow) { // close the current row
node in column i. But eventually,
20 last → right = head[currentRow];
the head nodes are linked
21 currentRow = t[i].row;
together through next (in line 30)
22 last = head[currentRow];
23 } // end of if
24 last = last → right = new MatrixNode(false, &t[i]); // link new node into row list
25 if ( head[t[i].col]→next==head[t[i].col] ) head[ t[i].col ]→down = head[ t[i].col ]→next=last;
else head[t[i].col]→next= head[t[i].col]→next→down= last; // linked into column list
26 } // end of for loop
27 last→ right = head[currentRow]; // close the last row
28 for (i = 0; i < s.col; i++) head[i] → next→ down = head[i]; // close all column lists
29 // linked the head nodes together
30 for (i = 0; i < p; i++) head[i] → next = head[i + 1];
Trick: head[i]→down should
31 head[p -1] → next = matrix.headnode;
point to the first matrix term
32 matrix.headnode→ right = head[0]; of column i. (line 25-1)
33 delete [ ] head; line 25-2 is executed for non-
34 return is; first column matrix term.
35 }J.-J. Chen, EE NTUST April 13, 2023 Linked List II-20
Erasing a Sparse Matrix (Prog.4-31)
Matrix :: ~Matrix()
{// return all nodes to the av list, this list is a chain linked via the right field.
// av is a global variable of type MatrixNode* and point to its first node
if (!headnode ) return; // no node to dispose
MatrixNode *x = headnode → right;
headnode → right = av; av = headnode; // return the headnode
while (x != headnode) { // erase by rows
MatrixNode *y = x → right;
x → right = av;
av = y;
x = x → next; // next row
}
headnode = 0;
}

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-21


Erasing a Circular List
template <class Type>
void CircularList<Type>::~CircularList()
//Erase the entire circular list pointed by first
{
if(first){
ListNode* second = first→link; // second node
first→link = av; // first node linked to av
av=second; // second node of list vecomes front of av list
first=0;
}
A circular list can be deleted in a fixed amount of time
}
→ independent of the number of nodes in the list88

First … … 0

available space
second
new av old av
J.-J. Chen, EE NTUST April 13, 2023 Linked List II-22
Chapter 4
Linked Lists(Part II)
•Equivalence Class
•Sparse Matrices
•Doubly Linked Lists
•Generalized Lists
•Virtual Functions & Dynamic Binding
•Heterogeneous Lists

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-23


Doubly linked list

Head node
Left Right

llink item rlink

Headnodes are convenient for algorithms,


they contain no data

__
first An empty list is not
really empty,
headnode is out there
J.-J. Chen, EE NTUST April 13, 2023 Linked List II-24
Class of doubly linked list
class Dblist;
class DblListNode{
friend class DblList;
private:
int data;
DblListNode *llink, *rlink;
};
class DblList{
public:
// lis manipulation operations
private:
DblListNode*first; // points to head node
};
J.-J. Chen, EE NTUST April 13, 2023 Linked List II-25
Deletion from doubly linked list
void DblList:: Delete(DblListNode *x)
{
if(x == first) cerr<<“Deletion of head node not permitted” << endl;
else{ x→llink→rlink=x→rlink;
x→rlink→llink=x→llink;
delete x;
}
}

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-26


Insertion into a doubly linked list
• void DblList::Insert(DbllistNode *p, DblListNode *x)
// insert node p to the right of node x
{
p→llink = x; p→rlink = x→rlink;
x→rlink→llink = p; x→rlink = p;
}

4 2

1 3

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-27


Chapter 4
Linked Lists(Part II)
•Equivalence Class
•Sparse Matrices
•Doubly Linked Lists
•Generalized Lists
•Virtual Functions & Dynamic Binding
•Heterogeneous Lists

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-28


Generalized List
• Definition
– A generalized list, A, is a finite sequence of n0
elements,(0,1,… ,n-1 ) where i is either an atom or a list.
• Head
– 0 is called the head of A
• Tail
– (1, … , n-1 ) is called the tail of A
• Recursive definition
– C=(a, C)=(a,(a,(a,…))), A=(a,(b, c)), B=(A, A,())
– A compact way of describing a large and varied
structure

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-29


Polynomial with Multiple Variables
• Example
– P(x, y, z)=x10y3z2 + x8y3z2 + x8y2z2 + x4y4z + x3y4z + 2yz
• Sequential representation
– Use a structure with four fields to represent a single array
element
• Coef., Exp_x, Exp_y, Exp_z

Coef Exp_x Exp_y


Exp_z Link

A polynomial term

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-30


Factored Form of Polynomial
• Variable order
– {z, y, x}
– z is the main variable, y is the 2nd, x is the 3rd
• Factored Expression

P(x,y,z)=x10y3z2 + x8y3z2 + x8y2z2 + x4y4z + x3y4z + 2yz

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-31


Variable independent PolyNode
enum Triple {var, ptr, no}
class PolyNode Case 1: trio == var→ head node
{ Case 2: trio == ptr→ coef is a sub-list pointed by dlink
PolyNode *link; Case 3: trio == no→ coeff is an integer
int exp;
Triple trio;
union{
char vble;
PolyNode *dlink; trio exp link
int coef;
} vble dlink coef
};

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-32


Polynomial in a General List
• Factored Expression

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-33


Representation of P(x,y,z)

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-34


Recursive Algorithms
• For recursively defined data object
– It is often easy to describe algorithms that
work on these objects recursively
• Two components in a recursive operation
1. Workhorse: the recursive function itself
• Often declared as a private function
2. Driver: the function that invokes the recursive
function at the top level
• Declared as a public function

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-35


Copying A General List
// Driver
void GenList::Copy (const GenList & l )
{
first = Copy( l.first )
}
// WorkHorse
GenListNode *GenList ::Copy(GenListNode *p)
// copy the recursive list with no shared sublists pointed at by p
{ p 1 2 3
GenLisNode *q = 0; tag dlink data link
if(p) {
q = new GenListNode; tag dlink data link
q→tag = p→tag;
if(!p→tag) q→data = p→data; // p is an atom node
else q→dlink = Copy(p→dlink); // p is a list pointer
q→link = Copy(p→link);
} Proof: by induction
return q; Complexity:O(m), or 3m steps
} Recursion depth:m
J.-J. Chen, EE NTUST April 13, 2023 Linked List II-36
General List Copy
Fig. 4.33

Fig. 4.34
Level of Value of p Continuing p Continuing p
recursion level level
1 b 2 r 3 u
2 s 3 u 4 v
3 t 4 w 5 0
4 0 5 x 4 v
3 t 6 0 3 u
2 s 5 x 2 0
1 b 4 w 3 r
2 b
1
J.-J. Chen, EE NTUST April 13, 2023 Linked List II-37
List Equality
// Driver- assumed to be a friend of GenList
int operator==(const GenList&l, const GenList&m)
// l and m are non-recursive lists
// The function returns 1 if the two lists are identical and 0, otherwise
{ return equal(l.first, m.first) }
// workhorse – assumed to be a friend of GenListNode
int equal(GenListNode* s, GenListNode *t)
{
int x;
if( (!s) && (!t) ) return 1; 1
if( s && t && (s→tag==t→tag ) )
{
Tag Data/ Link
if(!s→tag) Dlink 3
if(s→data == t→data) x=1; else x=0;
else x = equal(s→dlink, t→dlink); 2
if (x) return equal(s→link, t→link);
}
return 0;
}
J.-J. Chen, EE NTUST April 13, 2023 Linked List II-38
Depth of A General List
first
r
b t t 0
t u V
S f a f b 0 t f e 0
W X
f c f d 0

A has two sub-lists: b→dlink and r→dlink


Depth of list pointed by b→dlink: 1
Depth of list pointed by r→dlink: 2
→depth(A)=max(Depth(b),Depth(r)) +1 = 3

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-39


List Depth Computation
//Driver
int GenList::depth() // compute the depth of a non-recursive list
{ return (depth(first)) ;}

//workhorse
int GenList::depth(GenListNode *s)
{ first
if(!s) return 0;
r
GenListNode *p=s; int m=0; b t t 0
while(p) {
t u V
if (p→tag) { // list node S f a f b 0 t f e 0
int n = depth(p→dlink);
W X
if(m<n) m=n; f c f d 0
}
p=p→link; // move forward Depth(s)=
} 0
return m+1
1+max{depth(x1),…,depth(xn)}
}
if s is the list(x1,..,xn),n1
J.-J. Chen, EE NTUST April 13, 2023 Linked List II-40
General List with Sharing
tag data/down next Data/link of head node
→means reference count
A f 1 0 useful in decide when a node
can be returned to the storage pool

B f 3 f a t 0 B = (a, (b, c))

f 1 f b f c 0

C f 1 t t t 0 C = (B, B, ( ))

D f 2 f a t 0 f 1 0

B.~GenList( ); → B.ref=2; D = (a, D)


C.~GenList( ); → B.ref=0;
B=(a,(b,c)), C are returned to av;
J.-J. Chen, EE NTUST April 13, 2023 Linked List II-41
General List with Sharing
Data/link of head node
tag data/down next
→means reference count
a. first f 1 0 useful in decide when a node
can be returned to the storage pool

b. first f 3 f a t 0 B = (a, (b, c))

f 1
1. A call to t.~Genlist() should f bonly in fa c 0
result
decrementing by 1 of the reference counter of
c. first ft.first.
1 t t t 0 C = (B, B, ( ))

2. Only if the reference count becomes zero, the


d. first fnodes
2
of t fcould
a t 0
be physically f 1 0
returned to the
available-space list D = (a, D)

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-42


General List with Sharing
class GenListNode
{ Tag 0/1/2 data/dlink/ref link

friend class Genlist;


private:
GenListNode *link;
int tag; // 0 for data, 1 for dlink, 2 for ref
union {
char data;
GenListNode *dlink;
int ref;
}
}

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-43


Polynomials with Sharing

A B C D E F G H

I J K L M N O P Q R

S T U V

t=(3x4+5x3+7x)y3
u=(3x4+5x3+7x)y6 +(6x)y
J.-J. Chen, EE NTUST April 13, 2023 Linked List II-44
Erasing A List Recursively
//Driver
GenList::~GenList()
//Each head node has a reference count. We assume first  0.
{
Delete(first);
first =0;
}
//WorkHorse
void GenList::Delete(GenListNode*x)
{
x→ref - -; // decrement reference count of head node.
if(!x→ref)
{
GenListNode *y = x; // y traverses top-level of x.
while(y→link) { y = y→link; if (y→tag == 1) Delete(y→dlink);}
y→link = av; // attach top-level nodes to av list
av=x;
}
}
J.-J. Chen, EE NTUST April 13, 2023 Linked List II-45
Indirect Recursion Case
• For recursive list such as D=(a,D)
– The reference count will never be 1
– So, they cannot be recycled
• Indirect recursive lists cannot be recycled either

After calls to
A.~Genlist() and B.~Genlist()

A.first→ref=1 and B.first→ref=2

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-46


Chapter 4
Linked Lists(Part II)
•Equivalence Class
•Sparse Matrices
•Doubly Linked Lists
•Generalized Lists
•Virtual Functions & Dynamic Binding
•Heterogeneous Lists

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-47


Dynamic Binding
• Public inheritance
– Rectangle IS-A Polygon
– Rectangle has all attributes of Polygon
– Pointer to a derived class is implicitly converted to a pointer to its
bass class
• For example
– Rectangle r; // instance of derived class
– Polygon *s=&r; // assign rectangle to polygon
• Member function types
– Virtual functions
– Non-virtual functions
– Pure virtual functions
• The responsibility of the implementation is passed on to the
derived class

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-48


inheritance
class Polygon {
public:
int GetId(); // non-virtual member function
virtual Boolean Concave();
virtual int Perimeter() = 0; // pure virtual function
virtual char *Name();
protected:
int id;
}
class Rectangle: public Polygon // Rectangle publicly inherits from Polygon
{
public:
Boolean Concave(); // redefined in Rectangle
int Perimeter(); // redefined in Rectangle
// GetId() and id are inherited from Polygon
// they respectively, become public and protected members of Rectangle
private: // additional data members required to specialize rectangle
int x1, y1, h, w;
}
J.-J. Chen, EE NTUST April 13, 2023 Linked List II-49
inheritance
// GetId() must never be redefined in a derived class
int Polygon::GetId() {return id;}

//Default implementation of Concave() in polygon. A polygon is concave


// if it is possible to construct a line joining two points in the polygon
// that does not entirely lie within the polygon

Boolean Polygon::Concave() { return TRUE; }


//rectangle must define Perimeter() because it is a pure virtual function
//concave:凹面的
int Rectangle::Perimeter() { return 2*(h+w); }
// the default implementation of Concave() does not apply to rectangles
// so, it has to be redefined
Boolean Rectangle::Concave() {return FALSE;}

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-50


Rectangle & Triangle Class

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-51


Examples

Output:

Polygon ---Polygon Concave 1


Triangle ---Polygon Concave 0
Rectangle ---Polygon Concave 0

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-52


Chapter 4
Linked Lists(Part II)
•Equivalence Class
•Sparse Matrices
•Doubly Linked Lists
•Generalized Lists
•Virtual Functions & Dynamic Binding
•Heterogeneous Lists

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-53


Using Union for Mixed Nodes
struct Data
{ int id; // id= 0, 1, or 2 if the node contains
a char, an int, or float, respectively
union { int i; char c; float f; }
} // use union to merge different node types into one class

class CombinedNode { class List {


friend class List; friend class ListIterator;
friend class ListIterator; public: // List manipultaion
operations…/
private: private:
Data data; CombinedNode *first;
CombinedNode *link; }
};

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-54


Use Public Inheritance for A List of Mixed Nodes
class Node{ template<class T>
friend class List; class DerivedNode:public Node{
friend class ListIterator; friend class List;
protected: friend class ListIterator;
Node *link; public:
virtual Data GetData()=0; DerivedNode(T item):data(item) {link=0;};
}; private:
T data;
Data GetData();
};

Data DerivedNode<char>::GetData();
{ Data t; t.id=0; t.c=data; return t; }
// the implementations of GetData() for DerivedNode<int> and
// derivedNode<float> are similar to that of
DerivedNode<char>::GetData()

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-55


Data DerivedNode<int>::GetData();
{ Data t; t.id = 1; t.i = data; return t; }

Data DerivedNode<float>::GetData();
{ Data t; t.id = 2; t.f = data; return t; }

J.-J. Chen, EE NTUST April 13, 2023 Linked List II-56


Use public inheritance for a list for Mixed Nodes (2)
class List {
friend class ListIterator;
public: // List manipulation operations follow
class ListIterator{ private: Node *first;
public: }
ListIterator(const List&l): list(l), current(l.first) { };
Data *First(); // minor change in homogeneous list implementation
Data Next(); // minor change in homogeneous list implementation
Boolean NotNull(); // implemented as for homogeneous lists
private:
const List& list; Node *current; Data temp;
};
Data *ListIterator::First() {
if(list.first) {
temp = list.first →GetData(); // use GetData to retrieve element
return &temp;
}
return (0);
}J.-J. Chen, EE NTUST April 13, 2023 Linked List II-57
dynamic binding through public
inheritance
• KeyPoint
– A pointer to Node*(i.e. link) may be used to point to
nodes of type DerivedNode<char>, DerivedNode<int>
and DerivedNode<float>

Heterogeneous List homogeneous List


(Derived Node) (Combined Node)

derived
class

base class
J.-J. Chen, EE NTUST April 13, 2023 Linked List II-58

You might also like