Data structure

Download Report

Transcript Data structure

Linked List (Part I)
Introduction

Weakness of storing an ordered list in array:
 Insertion and deletion of arbitrary elements are
expensive.
○ Example:
Given an array which is arranged in ascending order.
2
4
6
7
○ Discuss how to insert a new element ‘1’ and how to
delete the element ‘4’.
 Storage allocation is not flexible.
Possible Improvements

The elements in an ordered list don’t
need to be stored in consecutive
memory space.
 The insertion and deletion of an element will
not induce excessive data movement.

The element can be “dynamically”
allocated.
Linked Representation

Data structure for a linked list:
first
Node
•Data
•Link (pointer): used to store the address of the next node.
Example
first
8
BAT
3
CAT
4
FAT
1
2
3
CAT
4
4
FAT
0
BAT
3
5
6
first
7
8
8
9
0
0
Insertion

Insert EAT into an ordered linked list
first
8
BAT
3
EAT
CAT
EAT
1
4
6
FAT
EAT
4
0
0
EAT
Find the position where EAT is
to be inserted.
2
3
CAT
4
6
1) Get a new node a
4
FAT
0
2) Set the data field of a to EAT.
5
6
first
7
8
8
9
EAT
4
BAT
3
3) Set the link field of a to point
the node after CAT, which
contains FAT.
4) Set the link field of the node
containing CAT to a.
Deletion

Remove CAT from the linked list
first
8
BAT
3
6
CAT
6
EAT
4
FAT
0
1
2
Find the address of CAT
3
CAT
6
1) Set the link of BAT to EAT.
4
FAT
0
2) Deallocate CAT
EAT
4
BAT
3
6
5
6
first
7
8
8
9
Representation of a Linked List
class ListNode
{
friend class LinkedList;
public:
ListNode();
ListNode(DataField value);
~ListNode();
private:
DataField data;
ListNode *link;
};
class LinkedList {
private:
ListNode
ListNode* first;
* first;
};
first
data
link
Linked Ordered List
Suppose elements are arranged in ascending
order.
 ADT

class LinkedOrderedList
{
public:
LinkedOrderedList();
~ LinkedOrderedList();
void Insert(DataField value);
bool Delete(DataField value); //return false if value is not found.
bool IsEmpty();
private:
ListNode *first;
};
Initialization

The constructor of ListNode:
ListNode::ListNode(DataField value)
{
data = value;
link = NULL;
}

The constructor of LinkedOrderedList:
LinkedOrderList::LinkedOrderList()
{
first = NULL;
}
Algorithm of Insert()
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
void LinkedOrderList::Insert(DataField value)
{
curr = first;
while (curr != NULL)
{
if (curr->data >= value)
{
ListNode *a = new ListNode(value);
a->link = curr;
previous->link = a;
break;
}
previous = curr;
curr = curr->link;
}
}
Insertion

Insert EAT into an ordered linked list
first
8
previous
previous
BAT
CAT
curr
3
FAT
curr
a
03
04
05
06
07
08
09
10
11
12
13
14
15
4
6
curr
EAT
4
curr = first;
while (curr != NULL)
{
if (curr->data >= value)
{
ListNode *a = new ListNode(value);
a->link = curr;
previous->link = a;
break;
}
previous = curr;
curr = curr->link;
}
0
Boundary Condition: Case 1

Consider to insert AT.
first
BAT
CAT
FAT
AT
 There will be no previous node for AT.
 The update of first is required.
Boundary Condition: Case 2

Consider to insert GAT.
first
BAT
CAT
FAT
GAT
03
04
05
06
07
08
09
10
11
12
13
14
15
curr = first;
while (curr != NULL)
{
if (curr->data >= value)
{
ListNode *a = new ListNode(value);
a->link = curr;
previous->link = a;
break;
}
No statement is written to insert
previous = curr;
GAT at the end of the list.
curr = curr->link;
}
Problem of Insert()

The function Insert() fails to deal with
boundary conditions.
 The insertion is always performed between two
existing nodes.

Improvements
 Add codes before- and after the while-statement
for dealing with the boundary conditions.
 Always maintain two (dummy) nodes so that
insertion can always be performed between two
nodes.
Improvement Using Two Dummy
Nodes

Maintain two dummy nodes at each end
of the list.
first
class LinkedList {
private:
ListNode * first, *last;
};
LinkedOrderList::LinkedOrderList()
{
first = new ListNode();
last = new ListNode();
first->link = last;
last->link = NULL;
}


last
No need to update the pointer first.
Boundary conditions are
eliminated (Insertion and Deletion
always take place between two
nodes).
New Version of Insert()
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
void LinkedOrderList::Insert(DataField value)
{
previous = first;
curr = first->link;
while (curr != NULL)
{
if (curr == last || curr->data >= value)
{
ListNode *a = new ListNode(value);
a->link = curr;
previous->link = a;
break;
}
previous = curr;
curr = curr->link;
}
}
Algorithm of Delete()
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
bool LinkedOrderList::Delete(DataField value)
{
if (IsEmpty())
return false;
previous = first;
curr = first->link;
while (curr != last)
{
if (curr->data == value)
{
previous->link = curr->link;
Deallocate curr;
return true;
}
previous = curr;
curr = curr->link;
}
return false;
}
Deletion

Consider to remove BAT from the list.
first
last
BAT
previous
10
11
12
13
14
15
curr
curr->link
if (curr->data == value)
{
previous->link = curr->link;
Deallocate curr;
return true;
}
Destruction of Nodes

Remember to deallocate each node in
the destructor.
01
02
03
04
05
06
07
08
09
10
LinkedOrderList ::~ LinkedOrderList()
{
curr = first;
while (curr != NULL)
{
next = curr->link;
Deallocate curr;
curr = next;
}
}
Performance Analysis

Suppose there are n nodes in a linked list.
 Space complexity:
○ A linked list uses an exact amount of memory space to
store these n nodes.
○ Space complexity to perform a insertion or deletion
O(1).
 Time complexity to perform a insertion or deletion:
○ Consider a worst case in which nodes are always
inserted and deleted at the end of the list. Therefore,
the complexity is O(n).
○ Excessive request of allocation or deallocation of
memory space for a node increases loading for the OS
system (and may lower efficiency).
Linked Stack
data
top
link
Pop
Pop
Push D
B
D
A
C
E
0
Linked Queue

Deletion takes place at front; insertion at
rear.
front
B
rear
C
Pop
Pop
Push E
D
A
E
0
Implementation of Linked Queue
LinkedQueue:: LinkedQueue()
{
front = rear = NULL;
};
bool LinkedQueue::IsEmpty()
{
if (front is NULL and rear is NULL)
return true;
return false;
}
Implementation of Linked Queue
Datafield LinkedQueue::Pop()
{
if (IsEmpty())
output error;
else
{
delNode = front;
value = front->data;
front = front->link;
deallocate delNode;
return value;
}
};
void LinkedQueue::Push(Datafield value)
{
if (IsEmpty())
front = rear = new ListNode(value);
else
rear = rear->link = new ListNode(value);
};
LinkedQueue::~ LinkedQueue()
{
while (!IsEmpty())
Pop();
};
Comparison

Compare stack/queue implemented
using array and linked stack/queue.
Array
Memory space
The length of an array is
fixed; Resize() is required
if the stack is full.
Execution time for The time complexity is
Push() and Pop() O(1).
Linked list
Memory space can be
dynamically allocated. The
storage is more compact.
The time complexity is also
O(1). But the memory
request increase overhead.
Polynomial Representation
class ListNode
{
friend class LinkedList;
public:
ListNode(int c, int e);
~ListNode();
private:
int coef, exp;
ListNode *link;
};
f(x) =3x2+1
first
3
2
coef exp
class Polynomial {
private:
ListNode *first;
};
1
0
Adding Polynomial

Example
 Consider the following two polynomials:
a(x) =3x14+2x8+1
b(x) =8x14-3x10+10x6
a.first
3
14
2
8
1
-3
10
10
0
0
ai
b.first
8
14
bi
6
0
Case 1

ai->exp == bi->exp
3
14
2
8
1
0
0
ai
8
14
-3
10
10
6
0
Add coefficients and append to
the result C.
bi
Advance ai and bi to next term.
C.first
11
14
0
Case 2

ai->exp < bi->exp
3
14
2
8
1
0
0
ai
8
14
-3
10
10
bi
14
-3
10
0
Advance bi to next term.
C.first
11
6
Append the term indicated by bi
to the result C.
0
Case 3

ai->exp > bi->exp
3
14
2
8
1
0
0
Append the term indicated by ai
to the result C.
ai
Advance ai to next term.
8
14
-3
10
10
6
0
bi
C.first
11
14
-3
10
2
8
10
6
1
0
0
Algorithm of Add()
LinkedPolynomial LinkedPolynomial::Add(Polynomial B)
{
Create a new LinkedPolynomial C as result;
ai = first;
bi = B.first;
while (ai != NULL && bi != NULL)
{
if (ai->exp == bi->exp) {
Sum = ai->coef + bi->coef;
if (Sum != 0)
C.InsertBack(Sum, ai->exp);
ai = ai->link;
bi = bi->link;
}
else if (ai->exp < bi->exp) {
C.InsertBack(bi->coef, bi->exp);
bi = bi->link;
}
else if (ai->exp > bi->exp) {
C.InsertBack(ai->coef, ai->exp);
ai = ai->link;
}
}
for (; ai != NULL; ai = ai->link) C.InsertBack(ai->coef, ai->exp);
for (; bi != NULL; bi = bi->link) C.InsertBack(bi->coef, bi->exp);
return C;
}