4 linked-list data structures linked-lists: singly-linked-lists, doubly-linked-lists insertion ...

34
4 Linked-List Data Structures Linked-lists: singly-linked-lists, doubly-linked-lists Insertion Deletion Searching © 2008 David A Watt, University of Glasgow Algorithms & Data Structures (M)

Upload: carly-jewel

Post on 16-Dec-2015

282 views

Category:

Documents


1 download

TRANSCRIPT

4Linked-List Data Structures

Linked-lists: singly-linked-lists, doubly-linked-lists

Insertion

Deletion

Searching

© 2008 David A Watt, University of Glasgow

Algorithms & Data Structures (M)

4-2

Linked-lists (1)

A linked-list consists of a header together with a sequence of nodes connected by links:

– Each node (except the last) has a successor node.

– Each node (except the first) has a predecessor node.

– Each node contains a single element (value or object), plus links to its successor and/or predecessor.

ant bat cat

header null linklinknode element

ant bat cat

4-3

Linked-lists (2)

The length of a linked-list is its number of nodes.

An empty linked-list has no nodes.

We can manipulate a linked-list’s elements.

We can also manipulate a linked-list’s links, and thus change its very structure! E.g.:

ant bat catBefore:

ant bat catAfter:

whereas an array’s structure can’t be changed

4-4

Singly-linked-lists (1)

A singly-linked-list (SLL) consists of a header together with a sequence of nodes connected by links in one direction only:

– Each SLL node contains a single element, plus a link to the node’s successor (or null if the node has no successor).

– The SLL header contains a link to the SLL’s first node (or a null link if the SLL is empty).

pig dog ratcat

dog

empty SLL

4-5

Singly-linked-lists (2)

Java class implementing SLLs:

public class SLL {// Each SLL object is the header of a // singly-linked-list. 

private SLL.Node first;

public SLL () {// Construct an empty SLL.this.first = null;

}

… methods (to follow)

4-6

Singly-linked-lists (3)

Java class implementing SLLs (continued):////////// Inner class //////////

private static class Node {// Each SLL.Node object is a node of a // singly-linked-list.

protected Object element;protected Node succ;

public Node (Object elem, Node succ) {

this.element = elem;this.succ = succ;

}

}

}

4-7

Example: SLL traversal

Method to traverse a SLL (in class SLL):

public void printFirstToLast () {// Print all elements in this SLL, in first-to-last order.

SLL.Node curr = this.first;while (curr != null) {

System.out.println(curr.element);curr = curr.succ;

}}

Animation:

ant bat catfirst ant bat catfirst

curr

ant bat catfirst

curr

ant bat catfirst

curr

ant bat catfirst

curr

4-8

ant bat catfirst ant bat catfirst

Example: SLL manipulation

Method to delete a SLL’s first node (in class SLL):

public void deleteFirst () {// Delete this SLL’s first node (assuming length > 0).

this.first = this.first.succ;}

Animation:

4-9

Insertion

Problem: Insert a new element at a given point in a linked-list.

Four cases to consider:

A. insertion in an empty linked-list;

B. insertion before the first node of a non-empty linked-list;

C. insertion after the last node of a non-empty linked-list;

D. insertion between nodes of a non-empty linked-list.

The insertion algorithm needs links to the new node’s successor and predecessor.

4-10

SLL insertion (1)

SLL insertion algorithm:

To insert elem at a given point in the SLL headed by first:

1. Make ins a link to a newly-created node with element elem

and successor null.2. If the insertion point is before the first node:

2.1. Set ins’s successor to first.2.2. Set first to ins.

3. Else, if the insertion point is after the node pred:3.1. Set ins’s successor to pred’s successor.3.2. Set pred’s successor to ins.

4. Terminate.

cases A, B

cases C, D

4-11

bat catfirst

To insert elem at a given point in the SLL headed by first:1. Make ins a link to a newly-created node with element elem and successor null.

2. If the insertion point is before the first node:2.1. Set ins’s successor to first.2.2. Set first to ins.

3. Else, if the insertion point is after the node pred:3.1. Set ins’s successor to pred’s successor.3.2. Set pred’s successor to ins.

4. Terminate.

elem antant

bat catfirst

ins

To insert elem at a given point in the SLL headed by first:1. Make ins a link to a newly-created node with element elem and successor null.

2. If the insertion point is before the first node:2.1. Set ins’s successor to first.2.2. Set first to ins.

3. Else, if the insertion point is after the node pred:3.1. Set ins’s successor to pred’s successor.3.2. Set pred’s successor to ins.

4. Terminate.

elem antant

bat catfirst

ins

To insert elem at a given point in the SLL headed by first:1. Make ins a link to a newly-created node with element elem and successor null.

2. If the insertion point is before the first node:2.1. Set ins’s successor to first.2.2. Set first to ins.

3. Else, if the insertion point is after the node pred:3.1. Set ins’s successor to pred’s successor.3.2. Set pred’s successor to ins.

4. Terminate.

elem antant

bat catfirst

ins

To insert elem at a given point in the SLL headed by first:1. Make ins a link to a newly-created node with elementelem and successor null.

2. If the insertion point is before the first node:2.1. Set ins’s successor to first.2.2. Set first to ins.

3. Else, if the insertion point is after the node pred:3.1. Set ins’s successor to pred’s successor.3.2. Set pred’s successor to ins.

4. Terminate.

elem antant

bat catfirst

To insert elem at a given point in the SLL headed by first:1. Make ins a link to a newly-created node with elementelem and successor null.

2. If the insertion point is before the first node:2.1. Set ins’s successor to first.2.2. Set first to ins.

3. Else, if the insertion point is after the node pred:3.1. Set ins’s successor to pred’s successor.3.2. Set pred’s successor to ins.

4. Terminate.

elem ant

SLL insertion (2)

Animation (insertion before first node):

4-12

dog foxfirst

To insert elem at a given point in the SLL headed by first:1. Make ins a link to a newly-created node with element elem and successor null.

2. If the insertion point is before the first node:2.1. Set ins’s successor to first.2.2. Set first to ins.

3. Else, if the insertion point is after the node pred:3.1. Set ins’s successor to pred’s successor.3.2. Set pred’s successor to ins.

4. Terminate.

pred eelelem

dog foxfirst

To insert elem at a given point in the SLL headed by first:1. Make ins a link to a newly-created node with element elem and successor null.

2. If the insertion point is before the first node:2.1. Set ins’s successor to first.2.2. Set first to ins.

3. Else, if the insertion point is after the node pred:3.1. Set ins’s successor to pred’s successor.3.2. Set pred’s successor to ins.

4. Terminate.

eelpred ins eelelem

dog foxfirst

To insert elem at a given point in the SLL headed by first:1. Make ins a link to a newly-created node with element elem and successor null.

2. If the insertion point is before the first node:2.1. Set ins’s successor to first.2.2. Set first to ins.

3. Else, if the insertion point is after the node pred:3.1. Set ins’s successor to pred’s successor.3.2. Set pred’s successor to ins.

4. Terminate.

eelpred ins eelelem

dog foxfirst

To insert elem at a given point in the SLL headed by first:1. Make ins a link to a newly-created node with element elem and successor null.

2. If the insertion point is before the first node:2.1. Set ins’s successor to first.2.2. Set first to ins.

3. Else, if the insertion point is after the node pred:3.1. Set ins’s successor to pred’s successor.3.2. Set pred’s successor to ins.

4. Terminate.

eelpred ins eelelem

dog foxfirst

To insert elem at a given point in the SLL headed by first:1. Make ins a link to a newly-created node with element elem and successor null.

2. If the insertion point is before the first node:2.1. Set ins’s successor to first.2.2. Set first to ins.

3. Else, if the insertion point is after the node pred:3.1. Set ins’s successor to pred’s successor.3.2. Set pred’s successor to ins.

4. Terminate.

eel eelelempred

SLL insertion (3)

Animation (insertion after intermediate node):

4-13

SLL insertion (4)

Implementation as a Java method (in class SLL):

public void insert (Object elem,SLL.Node pred) {

// Insert elem at a given point in this SLL, either after the

// node pred, or before the first node if pred is null.SLL.Node ins = new SLL.Node(elem,

null);if (pred == null) {

ins.succ = this.first;this.first = ins;

} else {ins.succ = pred.succ;pred.succ = ins;

}}

4-14

Deletion

Problem: Delete a given node from a linked-list.

Four cases to consider:

A. deletion of a singleton node;

B. deletion of the first (but not last) node;

C. deletion of the last (but not first) node;

D. deletion of an intermediate node.

The deletion algorithm needs links to the deleted node’s successor and predecessor.

4-15

SLL deletion (1)

SLL deletion algorithm:

To delete node del from the SLL headed by first:

1. Let succ be del’s successor.2. If del = first:

2.1. Set first to succ.3. Else:

3.1. Let pred be del’s predecessor.3.2. Set pred’s successor to succ.

4. Terminate.

cases A, B

cases C, D

But there is no link from node del to its predecessor, so step 3.1 can access del’s predecessor only by following links from first!

4-16

To delete node del from the SLL headed by first:1. Let succ be del’s successor.2. If del = first:

2.1. Set first to succ.3. Else:

3.1. Let pred be del’s predecessor.3.2. Set pred’s successor to succ.

4. Terminate.

ant bat catfirst

del

To delete node del from the SLL headed by first:1. Let succ be del’s successor.2. If del = first:

2.1. Set first to succ.3. Else:

3.1. Let pred be del’s predecessor.3.2. Set pred’s successor to succ.

4. Terminate.

ant bat catfirst

del succ

To delete node del from the SLL headed by first:1. Let succ be del’s successor.2. If del = first:

2.1. Set first to succ.3. Else:

3.1. Let pred be del’s predecessor.3.2. Set pred’s successor to succ.

4. Terminate.

ant bat catfirst

del succ

To delete node del from the SLL headed by first:1. Let succ be del’s successor.2. If del = first:

2.1. Set first to succ.3. Else:

3.1. Let pred be del’s predecessor.3.2. Set pred’s successor to succ.

4. Terminate.

ant bat catfirst

garbage

SLL deletion (2)

Animation (deleting the first node):

4-17

To delete node del from the SLL headed by first:1. Let succ be del’s successor.2. If del = first:

2.1. Set first to succ.3. Else:

3.1. Let pred be del’s predecessor.3.2. Set pred’s successor to succ.

4. Terminate.

dog eel foxfirst

del

To delete node del from the SLL headed by first:1. Let succ be del’s successor.2. If del = first:

2.1. Set first to succ.3. Else:

3.1. Let pred be del’s predecessor.3.2. Set pred’s successor to succ.

4. Terminate.

dog eel foxfirst

del succ

To delete node del from the SLL headed by first:1. Let succ be del’s successor.2. If del = first:

2.1. Set first to succ.3. Else:

3.1. Let pred be del’s predecessor.3.2. Set pred’s successor to succ.

4. Terminate.

dog eel foxfirst

del succpred

To delete node del from the SLL headed by first:1. Let succ be del’s successor.2. If del = first:

2.1. Set first to succ.3. Else:

3.1. Let pred be del’s predecessor.3.2. Set pred’s successor to succ.

4. Terminate.

dog eel foxfirst

del succpred

To delete node del from the SLL headed by first:1. Let succ be del’s successor.2. If del = first:

2.1. Set first to succ.3. Else:

3.1. Let pred be del’s predecessor.3.2. Set pred’s successor to succ.

4. Terminate.

dog eel foxfirst

garbage

SLL deletion (3)

Animation (deleting an intermediate node):

4-18

SLL deletion (4)

Analysis:

Let n be the SLL’s length.

Step 3.1 must visit all nodes from the first node to the deleted node’s predecessor. There are between 0 and n–1 such nodes.

Average no. of nodes visited = (n – 1)/2

Time complexity is O(n).

4-19

SLL deletion (5)

Implementation as a Java method (in class SLL):

public void delete (SLL.Node del) {// Delete node del from this SLL.

SLL.Node succ = del.succ;if (del == this.first) {

this.first = succ;} else {

SLL.Node pred = this.first;while (pred.succ != del)

pred = pred.succ;pred.succ = succ;

}}

4-20

Searching

Problem: Search for a given target value in a linked-list.

Idea: Follow links from the first node to the last node, terminating when we find a node whose element matches the target value.

4-21

SLL searching (1)

Unsorted SLL linear search algorithm:

To find which (if any) node of the SLL headed by first contains an element equal to target:

1. For each node curr in the SLL headed by first, repeat:1.1. If target is equal to curr’s element, terminate with

answer curr.2. Terminate yielding none.

4-22

SLL searching (2)

Analysis (counting comparisons):

Let n be the SLL’s length.

If the search is successful:

Average no. of comparisons = (n + 1)/2 n/2

If the search is unsuccessful:

No. of comparisons = n

In either case, time complexity is O(n).

4-23

SLL searching (3)

Implementation as a Java method (in class SLL):

public SLL.Node search (Object target) {// Find which (if any) node of this SLL contains an // element equal to target. Return a link to the // matching node (or null if there is none).

SLL.Node curr = this.first;while (curr != null) {

if (target.equals(curr.element))return curr;

curr = curr.succ;}return null;

}

4-24

Other SLL algorithms

Some other array algorithms can easily be adapted to SLLs:

– merging

– selection sort

– merge-sort

But not:

– binary search.

4-25

Doubly-linked-lists (1)

A doubly-linked-list (DLL) consists of a header together with a sequence of nodes connected by links in both direction:

– Each DLL node contains a single element, plus a link to the node’s successor (or null), plus a link to the node’s predecessor (or null).

– The DLL header contains links to the DLL’s first and last nodes (or null if the DLL is empty).

pig dog ratcat

dogempty DLL

4-26

Doubly-linked-lists (2)

Java class implementing DLLs:

public class DLL {// Each DLL object is the header of a // doubly-linked-list. 

private DLL.Node first, last;

public DLL () {// Construct an empty DLL.this.first = null;this.last = null;

}

… methods (to follow)

4-27

Doubly-linked-lists (3)

Java class implementing DLLs (continued):////////// Inner class //////////

private static class Node {// Each DLL.Node object is a node of a // doubly-linked-list.

protected Object element;protected Node pred, succ;

public Node (Object elem,Node pred, Node succ) {

this.element = elem;this.pred = pred; this.succ =

succ;}

}

}

4-28

Example: DLL traversal

Method to traverse a DLL (in class DLL):

public void printLastToFirst () {// Print all elements in this DLL, in last-to-first order.

DLL.Node curr = this.last;while (curr != null) {

System.out.println(curr.element);curr = curr.pred;

}}

Animation:

ant bat catfirstlast

ant bat catfirstlast

curr

ant bat catfirstlast

curr

ant bat catfirstlast

curr

ant bat catfirstlast

curr

ant bat catfirstlast

4-29

Example: DLL manipulation (1)

Method to delete a DLL’s first node (in class DLL):

public void deleteFirst () {// Delete this DLL’s first node (assuming length > 0).

DLL.Node second = this.first.succ;second.pred = null;this.first = second;

}

Animation:

ant bat catfirstlast

second

ant bat catfirstlast

second

ant bat catfirstlast

second

ant bat catfirstlast

4-30

Example: DLL manipulation (2)

Method to delete a DLL’s last node (in class DLL):

public void deleteLast () {// Delete this DLL’s last node (assuming length > 0).

DLL.Node penult = this.last.pred;penult.succ = null;this.last = penult;

}

Animation:

ant bat catfirstlast

penult

ant bat catfirstlast

penult

ant bat catfirstlast

penult

ant bat catfirstlast

4-31

DLL insertion (1)

DLL insertion algorithm:

To insert elem at a given point in the DLL headed by (first, last):

1. Make ins a link to a newly-created node with element elem

and with predecessor and successor both null.2. If first = last = null:

2.1. Set first to ins.2.2. Set last to ins.

3. Else, if the insertion point is before node first:3.1. Set ins’s successor to first.3.2. Set first’s predecessor to ins.3.3. Set first to ins.

4. Else, if the insertion point is after node last:4.1. Set ins’s predecessor to last.4.2. Set last’s successor to ins.4.3. Set last to ins.

4-32

DLL insertion (2)

DLL insertion algorithm (continued):

5. Else, if the insertion point is after the node pred and before

the node succ:5.1. Set ins’s predecessor to pred.5.2. Set ins’s successor to succ.5.3. Set pred’s successor to ins.5.4. Set succ’s predecessor to ins.

6. Terminate.

4-33

DLL deletion

DLL deletion algorithm:

To delete node del from the DLL headed by (first, last):

1. Let succ be del’s successor, and let pred be del’s successor.

2. If del = first:2.1. Set first to succ.

3. Else:3.1. Set pred’s successor to succ.

4. If del = last:4.1. Set last to pred.

5. Else:5.1. Set succ’s predecessor to pred.

6. Terminate.

4-34

Comparison of SLL and DLL algorithms

Algorithm SLL DLL

Insertion O(1) O(1)

Deletion O(n) O(1)

Search O(n) O(n)