• Nie Znaleziono Wyników

Programming and Data Structures Programming and Data Structures

N/A
N/A
Protected

Academic year: 2021

Share "Programming and Data Structures Programming and Data Structures"

Copied!
35
0
0

Pełen tekst

(1)

Programming and Data Structures Programming and Data Structures

Lecture 9 Lecture 9

Dr Piotr Cybula <piotr.cybula@wmii.uni.lodz.pl>

Dr Piotr Cybula <piotr.cybula@wmii.uni.lodz.pl>

(2)

Advanced operations on lists Advanced operations on lists

operations on the elements of a linked list do not require memory reallocation (modifications of pointer fields changing the order of nodes):

inversion of the list (changing the relationship between nodes by changing the address of the first node and the addresses of the next node)

removing a fragment of the list (skipping a fragment by changing the address of the next node in the node preceding the fragment and freeing memory)

moving a fragment within a list or between lists (skipping a fragment by changing the address of the next node in the node preceding the

fragment and changing the addresses of the next node in the new

preceding node and in the last node of the fragment)

(3)

Reversing Reversing

A next

C head

B next

(1) invoke two auxiliary pointers set on the adjacent nodes pred and succ (assume that the pointers next in the preceding nodes pointed to by succ are already inverted, succ is non- empty otherwise we abort, pred may be empty in the first step, head points to the node preceding succ)

(4)

Reversing Reversing

pred succ

(1) invoke two auxiliary pointers set on the adjacent nodes pred and succ (assume that the pointers next in the preceding nodes pointed to by succ are already inverted, succ is non- empty otherwise we abort, pred may be empty in the first step, head points to the node preceding succ)

(5)

Reversing Reversing

A C

head

B next

pred succ

(1) invoke two auxiliary pointers set on the adjacent nodes pred and succ (assume that the pointers next in the preceding nodes pointed to by succ are already inverted, succ is non- empty otherwise we abort, pred may be empty in the first step, head points to the node preceding succ)

(2) set the after pointer on the node following the one pointed to by succ

(6)

Reversing Reversing

pred succ after

(1) invoke two auxiliary pointers set on the adjacent nodes pred and succ (assume that the pointers next in the preceding nodes pointed to by succ are already inverted, succ is non- empty otherwise we abort, pred may be empty in the first step, head points to the node preceding succ)

(2) set the after pointer on the node following the one pointed to by succ

(7)

Reversing Reversing

A C

head

B next

pred succ after

(1) invoke two auxiliary pointers set on the adjacent nodes pred and succ (assume that the pointers next in the preceding nodes pointed to by succ are already inverted, succ is non- empty otherwise we abort, pred may be empty in the first step, head points to the node preceding succ)

(2) set the after pointer on the node following the one pointed to by succ (3) change the next pointer in the node pointed to by succ to the address pred

(8)

Reversing Reversing

pred succ after

(1) invoke two auxiliary pointers set on the adjacent nodes pred and succ (assume that the pointers next in the preceding nodes pointed to by succ are already inverted, succ is non- empty otherwise we abort, pred may be empty in the first step, head points to the node preceding succ)

(2) set the after pointer on the node following the one pointed to by succ (3) change the next pointer in the node pointed to by succ to the address pred

(9)

Reversing Reversing

A C

head

B next

pred succ after

(1) invoke two auxiliary pointers set on the adjacent nodes pred and succ (assume that the pointers next in the preceding nodes pointed to by succ are already inverted, succ is non- empty otherwise we abort, pred may be empty in the first step, head points to the node preceding succ)

(2) set the after pointer on the node following the one pointed to by succ (3) change the next pointer in the node pointed to by succ to the address pred (4) set the head and pred pointers to the node pointed to by succ

(10)

Reversing Reversing

pred succ after

(1) invoke two auxiliary pointers set on the adjacent nodes pred and succ (assume that the pointers next in the preceding nodes pointed to by succ are already inverted, succ is non- empty otherwise we abort, pred may be empty in the first step, head points to the node preceding succ)

(2) set the after pointer on the node following the one pointed to by succ (3) change the next pointer in the node pointed to by succ to the address pred (4) set the head and pred pointers to the node pointed to by succ

(11)

Reversing Reversing

A C

head

B next

pred succ after

(1) invoke two auxiliary pointers set on the adjacent nodes pred and succ (assume that the pointers next in the preceding nodes pointed to by succ are already inverted, succ is non- empty otherwise we abort, pred may be empty in the first step, head points to the node preceding succ)

(2) set the after pointer on the node following the one pointed to by succ (3) change the next pointer in the node pointed to by succ to the address pred (4) set the head and pred pointers to the node pointed to by succ

(5) set the succ pointer to the node pointed to by after

(12)

Reversing Reversing

pred succ

(1) invoke two auxiliary pointers set on the adjacent nodes pred and succ (assume that the pointers next in the preceding nodes pointed to by succ are already inverted, succ is non- empty otherwise we abort, pred may be empty in the first step, head points to the node preceding succ)

(2) set the after pointer on the node following the one pointed to by succ (3) change the next pointer in the node pointed to by succ to the address pred (4) set the head and pred pointers to the node pointed to by succ

(5) set the succ pointer to the node pointed to by after (6) if succ is not empty, go back to step (2)

(13)

Reversing Reversing

A C

head

B next

pred succ

next

(1) invoke two auxiliary pointers set on the adjacent nodes pred and succ (assume that the pointers next in the preceding nodes pointed to by succ are already inverted, succ is non- empty otherwise we abort, pred may be empty in the first step, head points to the node preceding succ)

(2) set the after pointer on the node following the one pointed to by succ (3) change the next pointer in the node pointed to by succ to the address pred (4) set the head and pred pointers to the node pointed to by succ

(5) set the succ pointer to the node pointed to by after (6) if succ is not empty, go back to step (2)

(14)

Reversing Reversing

(1) invoke two auxiliary pointers set on the adjacent nodes pred and succ (assume that the pointers next in the preceding nodes pointed to by succ are already inverted, succ is non- empty otherwise we abort, pred may be empty in the first step, head points to the node preceding succ)

(2) set the after pointer on the node following the one pointed to by succ (3) change the next pointer in the node pointed to by succ to the address pred (4) set the head and pred pointers to the node pointed to by succ

(5) set the succ pointer to the node pointed to by after (6) if succ is not empty, go back to step (2)

(15)

Fragment removal Fragment removal

A next

B C

head

next

B next

...

(1) invoke two auxiliary pointers: set pred to an empty address, and succ to the address of the first node (head) and pass them towards the end of the list so that the pred pointer stops at the node preceding the fragment, and succ at the first node in the fragment (otherwise we stop the operation)

(16)

Fragment removal Fragment removal

pred succ

(1) invoke two auxiliary pointers: set pred to an empty address, and succ to the address of the first node (head) and pass them towards the end of the list so that the pred pointer stops at the node preceding the fragment, and succ at the first node in the fragment (otherwise we stop the operation)

(17)

Fragment removal Fragment removal

A next

B C

head

next

B next

...

pred succ

(1) invoke two auxiliary pointers: set pred to an empty address, and succ to the address of the first node (head) and pass them towards the end of the list so that the pred pointer stops at the node preceding the fragment, and succ at the first node in the fragment (otherwise we stop the operation)

(2) invoke two auxiliary pointers: set end to succ, and after to the address of the next node behind succ and pass them towards the end of the list so that the end pointer stops at the last node of the fragment, and after on the first node after the fragment (it can be empty)

(18)

Fragment removal Fragment removal

pred succ end after

(1) invoke two auxiliary pointers: set pred to an empty address, and succ to the address of the first node (head) and pass them towards the end of the list so that the pred pointer stops at the node preceding the fragment, and succ at the first node in the fragment (otherwise we stop the operation)

(2) invoke two auxiliary pointers: set end to succ, and after to the address of the next node behind succ and pass them towards the end of the list so that the end pointer stops at the last node of the fragment, and after on the first node after the fragment (it can be empty)

(19)

Fragment removal Fragment removal

A next

B C

head

next

B next

...

pred succ end after

(1) invoke two auxiliary pointers: set pred to an empty address, and succ to the address of the first node (head) and pass them towards the end of the list so that the pred pointer stops at the node preceding the fragment, and succ at the first node in the fragment (otherwise we stop the operation)

(2) invoke two auxiliary pointers: set end to succ, and after to the address of the next node behind succ and pass them towards the end of the list so that the end pointer stops at the last node of the fragment, and after on the first node after the fragment (it can be empty)

(3) set a dedicated killer to the node pointed to by succ, and set succ to after

(20)

Fragment removal Fragment removal

pred killer end succ

(1) invoke two auxiliary pointers: set pred to an empty address, and succ to the address of the first node (head) and pass them towards the end of the list so that the pred pointer stops at the node preceding the fragment, and succ at the first node in the fragment (otherwise we stop the operation)

(2) invoke two auxiliary pointers: set end to succ, and after to the address of the next node behind succ and pass them towards the end of the list so that the end pointer stops at the last node of the fragment, and after on the first node after the fragment (it can be empty)

(3) set a dedicated killer to the node pointed to by succ, and set succ to after

(21)

Fragment removal Fragment removal

A next

B C

head

next

B next

...

pred killer end succ

(1) invoke two auxiliary pointers: set pred to an empty address, and succ to the address of the first node (head) and pass them towards the end of the list so that the pred pointer stops at the node preceding the fragment, and succ at the first node in the fragment (otherwise we stop the operation)

(2) invoke two auxiliary pointers: set end to succ, and after to the address of the next node behind succ and pass them towards the end of the list so that the end pointer stops at the last node of the fragment, and after on the first node after the fragment (it can be empty)

(3) set a dedicated killer to the node pointed to by succ, and set succ to after

(4) set the next pointer of the node pointed to by pred (or the head pointer when pred is empty) to the address stored in succ

(22)

Fragment removal Fragment removal

pred killer end succ

(1) invoke two auxiliary pointers: set pred to an empty address, and succ to the address of the first node (head) and pass them towards the end of the list so that the pred pointer stops at the node preceding the fragment, and succ at the first node in the fragment (otherwise we stop the operation)

(2) invoke two auxiliary pointers: set end to succ, and after to the address of the next node behind succ and pass them towards the end of the list so that the end pointer stops at the last node of the fragment, and after on the first node after the fragment (it can be empty)

(3) set a dedicated killer to the node pointed to by succ, and set succ to after

(4) set the next pointer of the node pointed to by pred (or the head pointer when pred is empty) to the address stored in succ

(23)

Fragment removal Fragment removal

A next

B C

head

next

B next

...

pred killer end succ

(1) invoke two auxiliary pointers: set pred to an empty address, and succ to the address of the first node (head) and pass them towards the end of the list so that the pred pointer stops at the node preceding the fragment, and succ at the first node in the fragment (otherwise we stop the operation)

(2) invoke two auxiliary pointers: set end to succ, and after to the address of the next node behind succ and pass them towards the end of the list so that the end pointer stops at the last node of the fragment, and after on the first node after the fragment (it can be empty)

(3) set a dedicated killer to the node pointed to by succ, and set succ to after

(4) set the next pointer of the node pointed to by pred (or the head pointer when pred is empty) to the address stored in succ

(5) set to the empty next pointer in the node pointed to by end

(24)

Fragment removal Fragment removal

pred killer end succ

(1) invoke two auxiliary pointers: set pred to an empty address, and succ to the address of the first node (head) and pass them towards the end of the list so that the pred pointer stops at the node preceding the fragment, and succ at the first node in the fragment (otherwise we stop the operation)

(2) invoke two auxiliary pointers: set end to succ, and after to the address of the next node behind succ and pass them towards the end of the list so that the end pointer stops at the last node of the fragment, and after on the first node after the fragment (it can be empty)

(3) set a dedicated killer to the node pointed to by succ, and set succ to after

(4) set the next pointer of the node pointed to by pred (or the head pointer when pred is empty) to the address stored in succ

(5) set to the empty next pointer in the node pointed to by end

(25)

Fragment removal Fragment removal

A next

B C

head

next

... B

pred killer end succ

(1) invoke two auxiliary pointers: set pred to an empty address, and succ to the address of the first node (head) and pass them towards the end of the list so that the pred pointer stops at the node preceding the fragment, and succ at the first node in the fragment (otherwise we stop the operation)

(2) invoke two auxiliary pointers: set end to succ, and after to the address of the next node behind succ and pass them towards the end of the list so that the end pointer stops at the last node of the fragment, and after on the first node after the fragment (it can be empty)

(3) set a dedicated killer to the node pointed to by succ, and set succ to after

(4) set the next pointer of the node pointed to by pred (or the head pointer when pred is empty) to the address stored in succ

(5) set to the empty next pointer in the node pointed to by end

(26)

Fragment removal Fragment removal

pred killer end succ

(1) invoke two auxiliary pointers: set pred to an empty address, and succ to the address of the first node (head) and pass them towards the end of the list so that the pred pointer stops at the node preceding the fragment, and succ at the first node in the fragment (otherwise we stop the operation)

(2) invoke two auxiliary pointers: set end to succ, and after to the address of the next node behind succ and pass them towards the end of the list so that the end pointer stops at the last node of the fragment, and after on the first node after the fragment (it can be empty)

(3) set a dedicated killer to the node pointed to by succ, and set succ to after

(4) set the next pointer of the node pointed to by pred (or the head pointer when pred is empty) to the address stored in succ

(5) set to the empty next pointer in the node pointed to by end

(6) release all nodes starting from the one pointed to by the killer to end (an independent list)

(27)

Fragment removal Fragment removal

(1) invoke two auxiliary pointers: set pred to an empty address, and succ to the address of the first node (head) and pass them towards the end of the list so that the pred pointer stops at the node preceding the fragment, and succ at the first node in the fragment (otherwise we stop the operation)

(2) invoke two auxiliary pointers: set end to succ, and after to the address of the next node behind succ and pass them towards the end of the list so that the end pointer stops at the last node of the fragment, and after on the first node after the fragment (it can be empty)

(3) set a dedicated killer to the node pointed to by succ, and set succ to after

(4) set the next pointer of the node pointed to by pred (or the head pointer when pred is empty) to the address stored in succ

(5) set to the empty next pointer in the node pointed to by end

(6) release all nodes starting from the one pointed to by the killer to end (an independent list)

A next

C

head pred succ

(28)

Fragment moving Fragment moving

pred begin end succ

(1) perform the first 5 steps of the removal algorithm by invoking the begin pointer in place of the killer (moving the tail pointer to the address stored in pred, when tail points to the node

pointed to by end)

(29)

Fragment moving Fragment moving

A next

B

C

head next

... B pred

begin end

succ tail

(1) perform the first 5 steps of the removal algorithm by invoking the begin pointer in place of the killer (moving the tail pointer to the address stored in pred, when tail points to the node

pointed to by end)

(2) the begin-end list is independent and can be safely moved:

(30)

Fragment moving Fragment moving

B next

... B pred

begin end

succ

(1) perform the first 5 steps of the removal algorithm by invoking the begin pointer in place of the killer (moving the tail pointer to the address stored in pred, when tail points to the node

pointed to by end)

(2) the begin-end list is independent and can be safely moved:

a) between any pair of pred and succ nodes (the next pointer from pred is set to begin, and the pointer next from end is set to succ)

(31)

Fragment moving Fragment moving

A next

B

C

head next

... B pred

begin end

succ tail

next

(1) perform the first 5 steps of the removal algorithm by invoking the begin pointer in place of the killer (moving the tail pointer to the address stored in pred, when tail points to the node

pointed to by end)

(2) the begin-end list is independent and can be safely moved:

a) between any pair of pred and succ nodes (the next pointer from pred is set to begin, and the pointer next from end is set to succ)

(32)

Fragment moving Fragment moving

B next

... B

begin end

(1) perform the first 5 steps of the removal algorithm by invoking the begin pointer in place of the killer (moving the tail pointer to the address stored in pred, when tail points to the node

pointed to by end)

(2) the begin-end list is independent and can be safely moved:

a) between any pair of pred and succ nodes (the next pointer from pred is set to begin, and the pointer next from end is set to succ)

b) to the beginning of the list (the next pointer from the end node is set to head, and then the head pointer to begin)

(33)

Fragment moving Fragment moving

A next B

C head

next

... B

begin end

tail next

(1) perform the first 5 steps of the removal algorithm by invoking the begin pointer in place of the killer (moving the tail pointer to the address stored in pred, when tail points to the node

pointed to by end)

(2) the begin-end list is independent and can be safely moved:

a) between any pair of pred and succ nodes (the next pointer from pred is set to begin, and the pointer next from end is set to succ)

b) to the beginning of the list (the next pointer from the end node is set to head, and then the head pointer to begin)

(34)

Fragment moving Fragment moving

B next

... B

begin end

(1) perform the first 5 steps of the removal algorithm by invoking the begin pointer in place of the killer (moving the tail pointer to the address stored in pred, when tail points to the node

pointed to by end)

(2) the begin-end list is independent and can be safely moved:

a) between any pair of pred and succ nodes (the next pointer from pred is set to begin, and the pointer next from end is set to succ)

b) to the beginning of the list (the next pointer from the end node is set to head, and then the head pointer to begin)

c) to the end of the list (set the next pointer from the tail node to begin, and then the tail pointer to end)

(35)

Fragment moving Fragment moving

(1) perform the first 5 steps of the removal algorithm by invoking the begin pointer in place of the killer (moving the tail pointer to the address stored in pred, when tail points to the node

pointed to by end)

(2) the begin-end list is independent and can be safely moved:

a) between any pair of pred and succ nodes (the next pointer from pred is set to begin, and the pointer next from end is set to succ)

b) to the beginning of the list (the next pointer from the end node is set to head, and then the head pointer to begin)

c) to the end of the list (set the next pointer from the tail node to begin, and then the tail pointer to end)

A next

B

C head

next

... B

begin end

tail

next

Cytaty

Powiązane dokumenty

● automatically created if (and only if) there are no explicit constructors, but without any initialisation of the fields (risky when there are any dynamically allocated fields in

● the public method changing the state of an object (modifier) is to check the compliance of such a change with the rules described by invariants. ● if the rules are exceeded,

● destructor, copy constructor and assignment operator (as for bounded) insertion/removal

(3) set a dedicated pointer (killer) to the last node using the address in the next pointer of the node pointed to by tmp (or the head pointer if tmp is empty, or the tail pointer

● during instantiation of a template with a specific type, the compiler replaces each instance of a parametric type with the specified type and compiles the data structure

(1) set the pred pointer on the node preceding the deleted node, and succ on the node to be removed (if there is no node we are looking for, throw an exception or abort the

(1) create two auxiliary pointers: set pred to an empty address, and succ on to the address of the first node (head) and pass the auxiliary pointers towards the end of the list

(1) by comparing values, go from root to children and set the pred pointer on the parent node to be removed, and succ on the node to be removed (if there is no node we are looking