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;
firstdata, firstlink
firstdata[0], firstdata[1], firstdata[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
 xx
 Symmetric
 If xy, then yx
 Transitive
 If xy and yz, then xz
 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
 04, 31, 610, 89, 74, 68, 35, 211, 110
 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
04, 31, 610, 89, 74, 68, 35, 211, 110
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 = xdata;
if (!out[j]) {
cout << ", " << j;
out[j] = true;
ENode *y = x link;
xlink = top;
top = x;
x = y;
}
else x = xlink;
}
if (!top) break;
x = first [topdata];
top = toplink; // 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