Upload
air-university-multan
View
150
Download
2
Tags:
Embed Size (px)
DESCRIPTION
...
Citation preview
Data Structures and Algorithms
Lecture 09
The List ADT
LinkedList Destructor, Circular LinkedList, Josephus ProblemReading: Weiss, chap.3
Slides Ref. Dr. Sohail Aslam (VU)
Space may be acquired at run-time on request from free store using new.
At a point in time when a memory area pointed to by a pointer is no longer required, it can be returned back to free store using delete.
We should always return storage after we no longer need it.
Once an area is freed, it is improper and quite dangerous to use it.
Dynamically Memory Allocation
Dangling References
ObjectTypeA *p, *q;
p = new ObjectTypeA;
q = p;
p
q
delete q; q = NULL;What happens to p?
p
q
It’s a “dangling reference”!
A dangling reference is an access path that continues to exist after the life time of the
associated data object.
Garbage
ObjectTypeA *p, *q;
p = new ObjectTypeA;
q = new ObjectTypeA;
q = p;
It’s “garbage”!
p
q
p
q
What happens to the space that was pointed to by q?
When all access paths to a data object are destroyed but the data
object continues to exist, the data object is said to be garbage.
Dangling References and Garbage
Dangling references are particularly serious problem for storage management, as they might compromise the integrity of the entire run-time structure during program execution.
Garbage is a less serious but still troublesome problem. A data object that has become garbage ties up storage that might otherwise be reallocated for another purpose.
A buildup of garbage can force the program to terminate prematurely because of lack of available free storage.
The Destructor
The destructor is the counterpart of the constructor.
It is a member function that is called automatically when a class object goes out of scope.
Its purpose is to perform any cleanup work necessary before an object is destroyed.
Destructors are required for more complicated classes, where they're used to release dynamically allocated memory.
~LinkedList() { }
LinkedList A; A.add(2); A.add(5); A.add(10); A.add(15); A.add(8);
A
Head 2 5 8 10 15 Æ
class Node { int data; Node *next; };Class LinkedList{private: Node * head;
public: … ~LinkedList(); };
• A goes out of scope. What Happens?• When destructor is called, what is deleted?
• What Happens to this memory area?
• It is garbage!• Destructor must also delete this area.
~LinkedList()~LinkedList()
{
Node *temp1, *temp2;
temp1 = head;
while (temp1 != NULL)
{
temp2 = temp1->next;
delete temp1;
temp1 = temp2;
}
}
A
Head 2 5 8 10 15 Æ
temp1temp2
Circularly-linked lists The next field in the last node in a singly-
linked list is set to NULL.
Moving along a singly-linked list has to be done in a watchful manner.
Doubly-linked lists have two NULL pointers: prev in the first node and next in the last node.
A way around this potential hazard is to link the last node with the first node in the list to create a circularly-linked list.
Cicularly Linked List Two views of a circularly linked list:
2 6 8 7 1head
current
size=5
2
8
7
1
head
current
size=5
6
Josephus Problem A case where circularly linked list comes in handy is
the solution of the Josephus Problem.
Consider there are 10 persons. They would like to choose a leader.
The way they decide is that all 10 sit in a circle.
They start a count with person 1 and go in clockwise direction and skip 3. Person 4 reached is eliminated.
The count starts with the fifth and the next person to go is the fourth in count.
Eventually, a single person remains.
Josephus Problem N=10, M=3
98
7
6
54
3
2
1
10
Josephus Problem N=10, M=3
98
7
6
54
3
2
1
10
eliminated
Josephus Problem N=10, M=3
9
8
7
6
54
3
2
1
10
eliminated
Josephus Problem N=10, M=3
9
8
7
6
54
3
2
1
10
eliminated
Josephus Problem N=10, M=3
9
8
7
6
54
3
2
1
10
eliminated
Josephus Problem N=10, M=3
9
8
7
6
54
3
2
1
10
eliminated
Josephus Problem N=10, M=3
9
8
7
6
54
3
2
1
10
eliminated
Josephus Problem N=10, M=3
9
8
7
6
54
3
2
1
10
eliminated
Josephus Problem N=10, M=3
9
8
7
6
54
3
2
1
10
eliminated
Josephus Problem N=10, M=3
9
8
7
6
54
3
2
1
10
eliminated
Josephus Problem#include "CList.cpp"
void main(int argc, char *argv[])
{
CList list;
int i, N=10, M=3;
for(i=1; i <= N; i++ ) list.add(i);
list.start();
while( list.length() > 1 ) {
for(i=1; i <= M; i++ ) list.next();
cout << "remove: " << list.get() << endl;
list.remove();
}
cout << "leader is: " << list.get() << endl;
}
Josephus Problem Using a circularly-linked list made the solution
trivial. The solution would have been more difficult if an
array had been used. This illustrates the fact that the choice of the
appropriate data structures can significantly simplify an algorithm. It can make the algorithm much faster and efficient.
Later we will see how some elegant data structures lie at the heart of major algorithms.
An entire CS course “Design and Analysis of Algorithms” is devoted to this topic.