Академический Документы
Профессиональный Документы
Культура Документы
STRUCTURES
WEEK 5-6-7
adeelmuzaffar@gmail.com
Outline
• Limitations of Arrays
• Definition
• Basic Operations
• Linked Stack, Queue and Priority Queue
• Implementation in C++
• Circular Linked List
• Doubly Linked List
• Case Study: Long Integers
3
Array Limitations
• Simple and Fast (indexed)
but
• Size fixed at construction time (static)
• Contiguous memory allocation
• Time consuming to do ordered insert
• have to shift lots of other data around
4
Ordered Array Insert
• Consider the following array
0 1 2 3 4 5 6 7 8
a c f m x
a c f k m x
Array vs. Linked List
array [0] [1] [2]
Array A B C
node
list
Linked list A B C
6
Linked List
• Definition
– a linked list is a collection or chain of nodes
– each node references the next node in chain
– last node references null
– Each node of the list contains
info next
• the data
• a pointer to the next node
node
– Head node Æfirst node
– Tail node Æ last node
7
A Linked List
Head Tail
8
A Node in C++
• Node stores a piece of data
• Node stores a pointer to another node
• Example:
struct Node
{
string name;
float grade;
Node* next;
};
9
Algorithmic Notations
• If p is a pointer to a node then node (p) refers to the
node pointed by p
• info(p) refers to the information portion of that node
• next(p) refers to the next field
p Info next
• p = getnode()
• freenode(p)
10
Inserting a front Node
p=getnode();
info(p) = x;
next(p)=list;
list = p;
11
Deleting the front Node
p= list;
list=next(p);
x= info(p);
freenode(p);
12
Traversing a Linked List
list
42 98 12 6
ptr
13
Traversing a Linked List
// Initialize the pointer ptr
ptr = list;
// traverse the list
while (ptr != NULL)
{
PROCESS info(ptr);
// increment ptr to point to next node
ptr = next(ptr);
}
14
An Example
• The following function finds the total number of nodes in a
linked list.
Count(List, Num)
{
Num = 0;
ptr = List;
while (ptr != NULL)
{
Num = Num+1;
ptr = next(ptr);
}
}
15
Insertion after a node
16
Insertion after a node
insafter(p, x)
{
q=getnode();
info(q)=x;
next(q)=next(p);
next(p)=q;
}
17
Deletion after a node
delafter(p,x)
{ q=next(p);
x=info(q);
next(p)=next(q);
freenode(q); }
18
Linked List in C++
struct node {
int info;
struct node* next; NODEPTR getnode()
}: {
typedef struct node* NODEPTR; NODEPTR p;
p=new node;
void freenode(NODEPTR p)
return(p);
{
}
delete(p);
}
19
Linked Stack and Queue
20
Linked Stack
Top of the Stack
NULL pointer
21
Push
s
22
Push
• create a new node for the item
• save data in the node
• link the new node to the current top node
• make the new node the new top
push (s, x)
{ p = getnode ();
info (p) = x;
next (p) = s;
s = p;
} 23
empty
empty (s)
{
if (s == NULL)
return TRUE;
else
return FALSE;
}
24
Pop
s
25
Pop
• check if the stack is empty
• remember address of current top node
• save the item in the top node
• make the next node the new top
• free the old top node
• return the item
26
Pop
pop (s)
{ if (empty (s))
Write: “Stack Underflow”;
else
{ p = s;
x = info (p);
s = next (p);
freenode (p); }
return x;
}
27
Linked Queue
front rear
28
Insert
front rear
front rear
29
Insertion in a Queue
• create a new node for the item
• if the queue is empty:
– the new node becomes both front and rear of the
queue
• otherwise:
– make a link from the current rear to the new
node
– the new node becomes the new rear
30
Insertion in a Queue
insert (q, x)
{
p = getnode ();
info (p) = x; next (p) = NULL;
if (q.rear == NULL)
q.front = p;
else
next (q.rear) = p;
q.rear = p;
}
31
Delete
front rear
front rear
32
Delete
• check that the queue is not empty
• save the item in the front node
• remember the address of the front node
• make the next node the new front
• free the old front node
• if queue is now empty, set rear to NULL
• return the item
33
Delete
remove (q, x)
{
if (empty (q)) Write: “Underflow”;
else
{
p = q.front;
x = info (p);
q.front = next (p);
if (q.front == NULL)
q.rear = NULL;
freenode (p);
}
}
34
Linked Priority Queue
Place (list, x)
{
q = null;
for (p = list; p != NULL && x > info (p); p = next (p))
q = p;
/* at this point new node must be inserted */
if (q == NULL)
push (list, x);
else
insafter (q, x);
}
35
Header Node
• A special node
• First node
• Global info
36
Linked List Class
37
template<class ItemType>
class List
{
protected:
struct node {
ItemType info;
struct node *next;
};
typedef struct node *NODEPTR;
NODEPTR listptr;
public:
List();
~List();
bool emptyList();
void insertafter(ItemType oldvalue, ItemType newvalue);
void deleteItem(ItemType oldvalue);
void push(ItemType newvalue);
ItemType pop();
};
38
// Default Constructor that initializes a newly created list to empty list.
template<class ItemType>
List<ItemType>::List()
{
listptr = 0;
}
40
// searches for the first occurance of oldvalue in the list and inserts a
new node with value newvalue following the node containing oldvalue.
template<class ItemType>
void List<ItemType>::insertafter(ItemType oldvalue, ItemType newvalue)
{
NODEPTR p, q;
for (p = listptr; p != 0 && p->info != oldvalue; p = p->next)
;
if (p == 0)
{ cout << " ERROR: value sought is not in the list.";
exit(1);
}
q = new node;
q->info = newvalue;
q->next = p->next;
p->next = q;
}
41
// deletes the first node containing the value oldvalue from the list.
template<class ItemType>
void List<ItemType>::deleteItem(ItemType oldvalue)
{
NODEPTR p, q;
for (q = 0, p = listptr; p != 0 && p->info != oldvalue;
q = p, p = p->next)
;
if (p == 0)
{ cout << " ERROR: value sought is not in the list.";
exit(1);
}
if (q == 0)
listptr = p->next;
else
q->next = p->next;
delete p;
}
42
// push(newvalue) adds a new node with a given value to
the front of the list
template<class ItemType>
void List<ItemType>::push(ItemType newvalue)
{
NODEPTR p;
p = new node;
p->info = newvalue;
p->next = listptr;
listptr = p;
}
43
// pop deletes the first node of the list and returns its
contents
template<class ItemType>
ItemType List<ItemType>::pop()
{
NODEPTR p;
ItemType x;
if (emptyList())
{ cout << " ERROR: the list is empty.";
exit(1); }
p = listptr;
listptr = p->next;
x = p->info;
delete p;
return x;
}
44
Circular Linked List
• The last node points to the first node
first
A B C
• If the linked list points to the last node rather than the first
node, it is very similar to the diagram in the previous slide
last
How do we refer to
A B C
the first node?
45
Circular Lists
list Empty list
list
Insert (list, x)
{ p = getnode();
info(p) = x;
if (list == null)
list = p;
else
next(p) = next(list);
next(list) = p;
} 47
Circular List: Concatenation
plist1
P O W E R
plist2
P O I N T
48
Circular List Concatenation
NODEPTR concat (NODEPTR plist1, NODEPTR plist2)
{
NODEPTR p;
if (plist2 == NULL)
return plist1;
if (plist1 == NULL)
{ plist1 = plist2;
return plist1;
}
p = plist1onext;
plist1onext = plist2onext;
plist2onext = p;
plist1 = plist2;
return plist1;
}
49
Circular List Application
Josephus Problem
read(n);
read(name);
while(name !=END) { insert name in the circular list;}
while (there is more than one node in the list)
{ count through n-1 nodes in the list;
print the name in the nth node;
delete the n node;
}
print the name of only node in the list
50
Doubly Linked List
A linked list in which each node contains two
pointers (right and left).
Head Tail
tail
struct node {
int info; If p is a pointer
node *left,*right; left(right(p)) = p = right(left(p))
};
52
Doubly Linked List: Deletion
q p r
void delete(NODEPTR p, int x)
{ NODEPTR q,r;
if (p==NULL)
cout<<“void deletion”;
x=pÆinfo;
q=pÆleft;
r=pÆright;
rÆleft=q;
qÆright=r;
freenode(p);
}
53
Doubly Linked List: Insertion
p r
void insertright(NODEPTR p, int x)
{
If(p==NULL)
cout <<“void insertion”;
q=getnode();
q
qÆinfo=x;
r=pÆright;
rÆleft=q;
qÆright=r;
qÆleft=p;
pÆright=q;
54
}
Case Study
55
Representation of Long Positive
Integers
• The hardware of most computers allows
integers of only a specific maximum length.
• Suppose we want to represent positive
integers of arbitrary lengths
• To add two such integers, their digits are
traversed from right to left, and the
corresponding digits and a possible carry
from the previous digit's sum are added.
56
Addition of Long Positive integers
• This suggests representing long integers by storing
their digits from right to left in a list so that:
• the first node contains the least significant
digits(rightmost)
• the last node contains most significant digits
(leftmost).
57
Long Integers Example
459763497210698463
459 76349 72106 98463
58
Addition of Long Positive integers
• To save space we keep five digits in each node
(long int will be used to store numbers as large as
99999).
• To add two such numbers, two list are traversed in
parallel, and five digits are added together.
• If the sum of two five digits numbers is x, the low
order five digits of x are extracted by using the
expression: x % 100000
• The carry can be computed by the integer division:
x / 100000
59
Long Integers Addition Example
60
Addition of Long Integers
• Let us consider extending the list implementation of
long integers to include negative as well as positive
integers.
62
Long Integers Addition Example
63
Addition of Long Integers
• If both lists have same number of nodes, the integer
with larger MSD has the greater absolute value. If
the MSDs of both numbers are same then it in
necessary to traverse the list from MSD to LSD.
• Note that this traversal is in direction opposite to
that of the traversal used in actually adding two
integers.
• Since we must be able to traverse the lists in
both directions, doubly linked list are used to
represents such integers.
64
Linked List: Conclusion
• Advantages
– can grow to “infinite” size
• only constrained by the size of memory
– very quick to insert or delete a node
• just move a few references around
• Disadvantage
– more difficult to implement than array
– can be very slow to search and access
• have to access each previous element to get the one desired
• Use a linked list instead of an array when
– the number of data elements is unpredictable
– the list needs to be sorted 65