Linked Lists - Professionals Forums | انجمن حرفه
Download
Report
Transcript Linked Lists - Professionals Forums | انجمن حرفه
Chapter 4
1
Why “linked lists”
Index
Word
A[0]
BAT
A[1]
CAT
A[2]
EAT
Insert “FAT” ?
Or delete something
…
A[n]
WAT
2
Usual way to draw a linked list
first
BAT
CAT
EAT
...
WAT 0
3
Inserting into a linked list
data
1 HAT
2
3 CAT
4 EAT
5 GAT
6
7 WAT
8 BAT
9 FAT
10
11 VAT
link
15
4
9
1
0
3
1
7
(a) 把 GAT 插入到 data [5]中
first
BAT
CAT
EAT
FAT
a
(b) 把 GAT 節點插入到串列中
HAT
...
GAT
4
Delete GAT
first
BAT
CAT
EAT
FAT
GAT
HAT
...
WAT 0
5
Defining a node in C++
class ThreeLetterNode
{
private:
char data[3];
ThreeLetterNode * link;
}
6
Example 4.1: The class definitions
class NodeA {
private:
int data1;
char data2;
float data3;
NodeA *linka;
NodeB *linkb;
};
class NodeB {
private:
int data;
NodeB *link;
};
data1
data2
data3
linka
linkb
55
‘c’
3.14
NodeA
data
link
22
NodeB
7
Designing a chain class in C++:
Design attempt 1
Use a global variable first which is a pointer of
ThreeLetterNode.
Unable to access to private data members: data and
link.
ThreeLetterNode *first;
firstdata, firstlink
firstdata[0], firstdata[1], firstdata[2]
*first
first→data
first
first→data[0]
first→data[1] first→data[2]
first→link
8
Designing a chain class in C++:
Design attempt 2
Make data members public or define public member
functions GetLink(), SetLink() and GetData()
Defeat the purpose of data encapsulation
The ideal solution would only permit those functions
that perform list manipulation operations (like
inserting a node into or deleting a node from a chain)
access to the data members of ThreeLetterNode
9
Designing a chain class in C++:
Design attempt 3
Use of two classes.
Create a class that represents the linked list.
The class contains the items of another objects of
another class.
HAS-A
A data object of type A HAS-A data object of type B if A
conceptually contains B or B is a part of A.
Eg. Computer HAS-A Processor, Book HAS-A Page
10
ThreeLetterChain
ThreeLetterNode
first
BAT
...
CAT
WAT 0
Conceptual relationship between ThreeLetterChain and ThreeLetterNode
ThreeLetterChain
ThreeLetterNode
first
BAT
CAT
...
WAT 0
Actual relationship between ThreeLetterChain and ThreeLetterNode
11
Program
4.1:
Composite
classes
class ThreeLetterChain; // forward declaration
class ThreeLetterNode {
friend class ThreeLetterChain;
private:
char data[3];
ThreeLetterNode *link;
};
class ThreeLetterChain {
public:
// Chain manipulation operations
.
.
private:
ThreeLetterNode *first;
};
12
Program 4.2: Nested classes
class ThreeLetterChain {
public:
// Chain Manipulation operations
.
.
private:
class ThreeLetterNode { // nested class
public:
char data[3];
ThreeLetterNode *link;
};
ThreeLetterNode *first;
};
13
Pointer manipulation in C++
Two pointer variables of the same type can be
compared.
Eg. x == y, x != y, x == 0
x
a
...
y
b
...
x
y
a
...
x
a
b
...
y
b
x=y
...
*x = *y
14
Program 4.3: Creating a two-node
list
void Chain::Create2()
{
// create and set fields of second node
ChainNode* second = new ChainNode(20,0);
// create and set fields of first node
first = new ChainNode(10,second);
}
first
10
20
0
15
Program 4.4: Inserting a node
void Chain::Insert50(ChainNode* x)
{
if ( first )
// insert after x
x→link = new ChainNode(50, x→link);
else
// insert into empty list
first = new ChainNode(50);
}
first
x
first
...
50
...
0
0
50
16
Program 4.5: Deleting a node
void Chain::Delete(ChainNode* x, ChainNode *y)
{
if(x = = first) first = first→link;
else y→link = x→link;
delete x;
}
Example:
Delete the
second node
Delete the
first node
Reference: J.L. Huang@NCTU
17
Program 4.6: Template definition of
chains
template < class T > class Chain;
template < class T >
class ChainNode {
friend class Chain <T>;
private:
T data;
ChainNode<T>* link;
};
template <class T>
class Chain {
public:
Chain( ) {first = 0;} // initializing first to 0
// Chain manipulation operations
.
.
private:
ChainNode<T> * first;
}
18
Iterator
An iterator is an object that is used to access the
elements of a container class one by one
void main( )
{
int x [3] = {0,1,2};
// use a pointer y to iterate the array x
for (int* y = x; y != x+3; y + +)
cout << *y << “ ”;
cout << endl;
}
19
Program 4.11: Inserting at the back
of a list
template < class T >
void Chain<T>::InsertBack( const T& e)
{
if (first) { // nonempty chain
last→link = new ChainNode<T>(e);
last = last→link;
}
else first = last = new ChainNode<T>(e);
}
20
Program 4.12: Concatenating two
chains
template < class T >
void Chain <T>::Concatenate(Chain<T>& b)
{ // b is concatenated to the end of *this
if ( first ) { last→link = b. first; last = b.last; }
else { first = b. first; last = b.last; }
b. first = b.last = 0;
}
21
Program 4.13: Reversing a list
template <class T>
void Chain<T>::Reverse()
{// A chain is reversed so that (a1, …, an) becomes (an, …, a1)
ChainNode<T> *current = first,
*previous = 0; // previous trails current
while (current) {
ChainNode<T> *r = previous;
previous = current; // r trails previous
current = current link; // current moves to next node
previous link = r; // link previous to preceding node
}
first = previous;
}
22
Circular lists
first
BAT
CAT
EAT
...
WAT
How to insert at the front of a circular list?
Read Program 4.14
23
Linked stacks and queues
data
link
top
rear
front
data
link
...
0
...
(b) 鏈結佇列
0
Read Program 4.19, 4.20, 4.21 and 4.22
(a) 鏈結堆疊
24
Program 4.23: Polynomial class
definition
struct Term
{
int coef;
int exp;
Term Set(int c,int e) {coef = c; exp = e; return *this;};
};
class Polynomial {
public:
// public functions defined here
private:
Chain<Term> poly;
};
25
Polynomial representation
a.poly.first
3
14
2
8
1
0
0
-3
10
10
6
0
(a)
b.poly.first
8
14
(b)
(a) 3x14+2x8+1
(b) 8x14-3x10+10x6
26
Adding polynomials: 3x14+2x8+1
and 8x14-3x10+10x6
27
28
29
Equivalence classes
For an arbitrary relation by the symbol
Reflexive
xx
Symmetric
If xy, then yx
Transitive
If xy and yz, then xz
A relation over a set, S, is said to be an equivalence
relation over S if and only if it is symmetric, reflexive,
and transitive over S.
30
Example
04, 31, 610, 89, 74, 68, 35, 211, 110
Three equivalent classes: {0,2,4,7,11}; {1,3,5}; {6,8,9,10}
31
Program 4.26: First version of
equivalence algorithm
void Equivalence()
{
initialize;
while more pairs
{
input the next pair (i,j);
process this pair;
}
initialize for output;
for(each object not yet output)
output the equivalence class that contains his
object;
}
32
Program 4.27: A more detail
version of equivalence algorithm
void Equivalence()
{
read n;
initialize first[0:n-1] to 0 and out[0:n-1] to false;
while more pairs
{
read the next pair (i, j);
put j on the chain first[i];
put i on the chain first[j];
}
for (i = 0; i < n; i++)
if (!out[i]) {
out[i] = true;
output the equivalence class that contains object i;
}
}
33
Lists after pairs have been input
04, 31, 610, 89, 74, 68, 35, 211, 110
first [0]
data
link
11
data
link
4
0
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
3
0
11
5
7
3
0
8
4
0
6
1
0
0
0
0
10
0
9
0
[9] [10] [11]
8
0
6
0
0
2
0
34
Program 4.28: C++ function to find
equivalence classes
class ENode {
friend void Equivalence( );
public:
ENode(int d = 0)
{data = d; link = 0;}
private:
int data;
ENode *link;
};
35
void Equivalence( )
{// input and output
ifstream inFile( "equiv.in", ios::in);
if (!inFile) throw “Cannot open input file.”;
int i, j, n;
inFile >> n; // read number of objects
// initialize first and out
ENode **first = new ENode* [n];
bool *out = new bool[n];
// use STL function fill to initialize
fill (first, first + n, 0);
fill (out, out + n, false);
36
// Phase 1: input equivalence pairs
inFile >> i >> j;
while (inFile.good()) { // check end of file
first[i] = new ENode (j, first[i])
first[j] = new ENode (i, first[j])
inFile >> i >> j;
}
37
// Phase 2: output equivalence classes
for (i = 0; i < n; i++)
if (!out[i]) { // needs to be output
cout << endl << "A new class: " << i;
out[i] = true;
ENode *x = first[i]; ENode *top = 0; // initialize stack
while (1) { //find rest of class
while (x) { // process the list
j = xdata;
if (!out[j]) {
cout << ", " << j;
out[j] = true;
ENode *y = x link;
xlink = top;
top = x;
x = y;
}
else x = xlink;
}
if (!top) break;
x = first [topdata];
top = toplink; // unstack
} // end of while(1)
38
}
for (i = 0; i < n; i++)
while (first[i]) {
ENode *delnode = first[i];
first[i] = delnode link;
delete delnode;
}
delete [] first; delete [] out;
}
39
Sparse matrices
2
4
0
8
0
0 0 0
0 0 3
0 0 0
0 0 1
0 6 0
1
next
down
row
right
down
0
4
col value
right
Next nonzero column
(a) 標頭節點
(b) 元素節點
head 欄位沒畫出來
Next nonzero row
40
Example
H
H0
H1
H2
H3
H4
4 5 6
H0
0 0 2
H1
1 0 4
1 3 3
3 0 8
3 3 1
H2
H3
Thus for an nxm sparse
matrix with r nonzero
terms, the number of
nodes needed is
max{n, m} + r + 1.
H4
4 2 6
41
Program 4.29: Class definition for
sparse matrices
struct Triple{int row, col, value;};
class Matrix;
class MatrixNode {
friend class Matrix;
friend istream& operator>>(istream&, Matrix&);
private:
MatrixNode *down , *right;
bool head;
union {
MatrixNode *next;
Triple triple;
};
MatrixNode(bool, Triple*); // constructor
}
42
MatrixNode::MatrixNode(bool b, Triple *t) // constructor
{
head = b;
if (b) {right = down = this;} // row/column header node
else triple = *t;
// element node or header node for list of header nodes
}
class Matrix{
friend istream& operator>>(istream&, Matrix&);
public:
~Matrix(); // destructor
private:
MatrixNode *headnode;
};
43
Doubly linked lists
Move in forward and backward direction.
How to get the preceding node during deletion or
insertion?
Using 2 pointers
Node in doubly linked list
left link field (left link)
data field (item)
right link field (right link)
44
Doubly linked circular list with
開頭節點
header node
left
data
right
-
Empty doubly linked circular list with header node
first
45
Program 4.32: Class definition of a
doubly linked list
class DblList;
class DblListNode {
friend class DblList;
private:
int data;
DblListNode *left, *right;
};
class DblList {
public:
// List manipulation operations
.
.
private:
DblListNode *first; // points to header node
};
46
Program 4.33: Deletion from a
doubly linked circular list
void DblList :: Delete(DblListNode *x)
{
if (x = = first) throw "Deletion of header node not permited";
else {
x→left→right = x→right; //(1)
x→right→left = x→left; //(2)
delete x;
}
Reference: J.L. Huang@NCTU
47
Program 4.34: Insertion into a
doubly linked circular list
void DblList :: Insert(DblListNode *p, DblListNode *x)
{ // insert node p to the right of node x
p→left = x; //(1)
p→right = x→right; //(2)
x→right→left = p; //(3)
x→right = p; //(4)
}
Reference: J.L. Huang@NCTU
48