Linked List (Part I). Introduction Weakness of storing an ordered list in array: Insertion and...

Post on 18-Jan-2016

216 views 0 download

transcript

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.

○ Discuss how to insert a new element ‘1’ and how to delete the element ‘4’.

Storage allocation is not flexible.

2 4 6 7

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

•Data•Link (pointer): used to store the address of the next node.

Node

Example

BAT 3 CAT 4 FAT 08

first

0

1

2

CAT 43

FAT 04

5

6

7

BAT 38

9

8

first

Insertion

BAT 3 CAT 4 FAT 08

first

0

1

2

CAT 43

FAT 04

5

6

7

BAT 38

9

8

first

Insert EAT into an ordered linked list

1) Get a new node a

2) Set the data field of a to EAT.3) Set the link field of a to point the node after CAT, which contains FAT.

Find the position where EAT is to be inserted.

EATEAT EATEAT

6 EAT6 EAT 46

EAT 4

CAT 6

CAT 63

4) Set the link field of the node containing CAT to a.

Deletion

BAT 3 CAT 6 EAT 48

first

1

2

CAT 63

FAT 04

5

EAT 46

7

BAT 38

9

8

first

Remove CAT from the linked list

1) Set the link of BAT to EAT.

2) Deallocate CAT

Find the address of CAT

FAT 0

BAT 68

BAT 6

3

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 * first;};

first

class LinkedList { private: ListNode * first;};

class ListNode { friend class LinkedList; public: ListNode(); ListNode(DataField value); ~ListNode(); private: DataField data; ListNode *link;}; 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:

The constructor of LinkedOrderedList:

LinkedOrderList::LinkedOrderList(){ first = NULL;}

ListNode::ListNode(DataField value){ data = value; link = NULL;}

Algorithm of Insert()

01 void LinkedOrderList::Insert(DataField value)02 {03 curr = first;04 while (curr != NULL) 05 {06 if (curr->data >= value)07 {08 ListNode *a = new ListNode(value);09 a->link = curr;10 previous->link = a;11 break;12 }13 previous = curr;14 curr = curr->link;15 }16 }

Insertion

BAT 3 CAT 4 FAT 08

first

Insert EAT into an ordered linked list

currcurr curr

EATEAT 4

CAT 6

previous previous

03 curr = first;04 while (curr != NULL) 05 {06 if (curr->data >= value)07 {08 ListNode *a = new ListNode(value);09 a->link = curr;10 previous->link = a;11 break;12 }13 previous = curr;14 curr = curr->link;15 }

a

Boundary Condition: Case 1 Consider to insert AT.

There will be no previous node for AT.The update of first is required.

BAT CAT FAT

first

AT

Boundary Condition: Case 2 Consider to insert GAT.

BAT CAT FAT

first

GAT

03 curr = first;04 while (curr != NULL) 05 {06 if (curr->data >= value)07 {08 ListNode *a = new ListNode(value);09 a->link = curr;10 previous->link = a;11 break;12 }13 previous = curr;14 curr = curr->link;15 }

No statement is written to insert GAT at the end of the list.

Problem of Insert()

The function Insert() fails to deal with boundary conditions.The insertion is always performed between two

existing nodes.

ImprovementsAdd 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.

class LinkedList { private: ListNode * first, *last;};

LinkedOrderList::LinkedOrderList(){ first = new ListNode(); last = new ListNode(); first->link = last; last->link = NULL;}

first 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 void LinkedOrderList::Insert(DataField value)02 {03 previous = first;04 curr = first->link;05 while (curr != NULL) 06 {07 if (curr == last || curr->data >= value)08 {09 ListNode *a = new ListNode(value);10 a->link = curr;11 previous->link = a;12 break;13 }14 previous = curr;15 curr = curr->link;16 }17 }

Algorithm of Delete()

01 bool LinkedOrderList::Delete(DataField value)02 {03 if (IsEmpty())04 return false;0506 previous = first;07 curr = first->link;08 while (curr != last) 09 {10 if (curr->data == value)11 {12 previous->link = curr->link;13 Deallocate curr;14 return true;15 }16 previous = curr;17 curr = curr->link;18 }19 return false;20 }

Deletion Consider to remove BAT from the list.

first last

BAT

10 if (curr->data == value)11 {12 previous->link = curr->link;13 Deallocate curr;14 return true;15 }

previous curr curr->link

Destruction of Nodes

Remember to deallocate each node in the destructor.

01 LinkedOrderList ::~ LinkedOrderList()02 {03 curr = first;04 while (curr != NULL) 05 {06 next = curr->link;07 Deallocate curr;08 curr = next;09 }10 }

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

B

A

C

E 0

data link

top Pop Pop

D

Push D

Linked Queue

Deletion takes place at front; insertion at rear.

B C D A E 0

front rear

Pop Pop Push E

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

void LinkedQueue::Push(Datafield value){ if (IsEmpty()) front = rear = new ListNode(value); else rear = rear->link = new ListNode(value);};

Datafield LinkedQueue::Pop(){ if (IsEmpty()) output error; else { delNode = front; value = front->data; front = front->link; deallocate delNode; return value; }};

LinkedQueue::~ LinkedQueue(){ while (!IsEmpty()) Pop();};

Comparison

Compare stack/queue implemented using array and linked stack/queue.

Array Linked list

Memory space The length of an array is fixed; Resize() is required if the stack is full.

Memory space can be dynamically allocated. The storage is more compact.

Execution time for Push() and Pop()

The time complexity is O(1).

The time complexity is also O(1). But the memory request increase overhead.

Polynomial Representation

class Polynomial { private: ListNode *first;};

first

class ListNode { friend class LinkedList; public: ListNode(int c, int e); ~ListNode(); private: int coef, exp; ListNode *link;};

3 2 1 0

f(x) =3x2+1

coef exp

Adding Polynomial

ExampleConsider the following two polynomials:

a(x) =3x14+2x8+1

b(x) =8x14-3x10+10x6

b.first

8 14 -3 10

bi

a.first

3 14 2 8

ai

1 00

10 06

Case 1

ai->exp == bi->exp

8 14 -3 10

bi

3 14 2 8

ai

1 00

C.first

11 014

Add coefficients and append to the result C.

Advance ai and bi to next term.

10 06

Case 2

ai->exp < bi->exp

8 14 -3 10

ai

3 14 2 8

bi

1 00

C.first

-3 010

Append the term indicated by bi to the result C.

Advance bi to next term.

11 14

10 06

Case 3

ai->exp > bi->exp

8 14 -3 10

bi

3 14 2 8

ai

1 00

C.first

-3 10

Append the term indicated by ai to the result C.

Advance ai to next term.

11 14

10 06

2 8 10 6 1 00

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;}