Array list: insert at position: Difference between revisions
No edit summary |
|||
(17 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
[[Category:Videos]] | |||
{{#ev:youtube|https://www.youtube.com/watch?v=uYTck0kDvl4|500|right||frame}} | |||
'''Algorithmic problem:''' [[Ordered sequence#Insert at position|Ordered sequence: insert at position]] | '''Algorithmic problem:''' [[Ordered sequence#Insert at position|Ordered sequence: insert at position]] | ||
'''Type of algorithm:''' loop | '''Type of algorithm:''' loop | ||
Line 7: | Line 7: | ||
'''Auxiliary data:''' | '''Auxiliary data:''' | ||
# A natural number sum <math>\in \mathbb{N}_0</math>, which contains the total number of all elements seen so far in the visited arrays. | # A natural number sum <math>\in \mathbb{N}_0</math>, which contains the total number of all elements seen so far in the visited arrays. | ||
# Two pointers, <math>p</math> and <math>p'</math>, of type "pointer | # Two pointers, <math>p</math> and <math>p'</math>, of type "pointer to array list item of type <math>\mathcal{K}</math>". | ||
==Abstract view == | ==Abstract view == | ||
Line 13: | Line 13: | ||
'''Invariant:'''After <math>i \ge 0</math> iterations: | '''Invariant:'''After <math>i \ge 0</math> iterations: | ||
# The pointer <math>p</math> points to the array at position <math>i+1</math> in the array list. | # The pointer <math>p</math> points to the array at position <math>i+1</math> in the array list. | ||
# It is <math> | # It is sum<math>= n_1 + \ldots + n_i</math>, where <math>n_j</math> is the value of the component n of the array list item at position <math>j \in \{1, \ldots,i\}</math>. | ||
''' | '''Variant:''' The pointer <math>p</math> is moved one step forward to the next array. | ||
'''Break condition:''' It is sum <math>+ p.n \ge | '''Break condition:''' It is sum <math>+ p.n \ge\ell</math>. | ||
==Induction basis== | ==Induction basis== | ||
'''Abstract view:''' Set <math>p:=</math>first and <math> | '''Abstract view:''' Set <math>p:=</math>first and sum<math>:=0</math>. | ||
'''Implementation:''' Obvious. | '''Implementation:''' Obvious. | ||
Line 29: | Line 29: | ||
==Induction step== | ==Induction step== | ||
'''Abstract view:''' If the position <math> | '''Abstract view:''' If the position <math>\ell</math> is in the current array, insert <math>K</math> (if the array is full, split it first). | ||
'''Implementation:''' | '''Implementation:''' | ||
# If sum<math>+ p.n < | # If <math>p=</math> void, terminate the algorithm and return '''false'''. | ||
# If sum<math>+ p.n < \ell</math>: | |||
## Set sum<math>:=</math>sum<math>+ p.n</math>. | ## Set sum<math>:=</math>sum<math>+ p.n</math>. | ||
## Set <math>p:=p | ## Set <math>p:=p</math>.next. | ||
#Otherwise: | #Otherwise: | ||
##If <math>p.n=N</math>: | ##If <math>p.n=N</math>: | ||
###Create a new array list item and let <math>p'</math> point to this new list item. | ###Create a new array list item and let <math>p'</math> point to this new list item. | ||
###Set <math>p'.next=p | ###Set <math>p'</math>.next<math>=p</math>.next. | ||
###Set <math>p.next:=p'</math>. | ###Set <math>p</math>.next<math>:=p'</math>. | ||
###For <math>j \in \{1, \ldots, \lfloor p.n/2 \rfloor \}</math>, set <math>p'.A[\lceil p.n/2 \rceil + j]</math> and <math>p.A[\lceil p.n/2 \rceil + j]:=</math>void. | ###For <math>j \in \{1, \ldots, \lfloor p.n/2 \rfloor \}</math>, set <math>p'.A[\lceil j \rceil]:=p.A[\lceil p.n/2 \rceil + j ]</math> and <math>p.A[\lceil p.n/2 \rceil + j]:=</math>void. | ||
###Set <math>p'.n:=\lfloor p.n/2 \rfloor</math> and, afterwards, <math>p.n:=p.n - \lfloor p.n/2 \rfloor</math>. | ###Set <math>p'.n:=\lfloor p.n/2 \rfloor</math> and, afterwards, <math>p.n:=p.n - \lfloor p.n/2 \rfloor</math>. | ||
## If <math>l - sum > p.n</math>: | ## If <math>l - </math>sum<math> > p.n</math>: | ||
### Set <math>m:=l - sum - p.n + 1</math>. | ### Set <math>m:=l -</math> sum <math> - p.n + 1</math>. | ||
### Set <math>p:=p'</math>. | ### Set <math>p:=p'</math>. | ||
## Otherwise, set <math>m:=l - sum + 1</math>. | ## Otherwise, set <math>m:=l -</math>sum<math>+ 1</math>. | ||
## For <math>j=p.n, \ldots, m</math> (in this order), set <math>p.A[j+1]:=p.A[j]</math>. | ## For <math>j=p.n, \ldots, m</math> (in this order), set <math>p.A[j+1]:=p.A[j]</math>. | ||
## Set <math>p.A[m]:=K</math>. | |||
# Return '''true'''. | |||
'''Correctness:''' Note that, in an implementation of [[ | '''Correctness:''' Note that, in an implementation of [[Ordered sequence#Insert at position|Ordered sequence: insert at position]], we may assume <math>l \leq</math>number(). Therefore, we do not have to care about the end of the list. In the case sum<math>+ p.n < l</math>, we simply have to update sum and <math>p</math>, which is obviously done correctly. So consider the case sum<math>+ p.n \ge l</math>, which means that the position where <math>K</math> has to be inserted is in the array list item to which <math>p</math> currently points. If that array is full, new space must be allocated. Step 2.1 does that and distributes the elements roughly equally over both items. Steps 2.2 - 2.3 ensure that <math>p</math> points to the array where to insert <math>K</math> and <math>m</math> identifies the correct insert position. Step 2.4 empties the array component where to insert the new element by moving, exactly one position forward, the value at the position and the values at all later position (which is possible because the array is not full in any case). | ||
==Complexity== | ==Complexity== |
Latest revision as of 12:57, 18 September 2015
Algorithmic problem: Ordered sequence: insert at position
Type of algorithm: loop
Auxiliary data:
- A natural number sum [math]\displaystyle{ \in \mathbb{N}_0 }[/math], which contains the total number of all elements seen so far in the visited arrays.
- Two pointers, [math]\displaystyle{ p }[/math] and [math]\displaystyle{ p' }[/math], of type "pointer to array list item of type [math]\displaystyle{ \mathcal{K} }[/math]".
Abstract view
Invariant:After [math]\displaystyle{ i \ge 0 }[/math] iterations:
- The pointer [math]\displaystyle{ p }[/math] points to the array at position [math]\displaystyle{ i+1 }[/math] in the array list.
- It is sum[math]\displaystyle{ = n_1 + \ldots + n_i }[/math], where [math]\displaystyle{ n_j }[/math] is the value of the component n of the array list item at position [math]\displaystyle{ j \in \{1, \ldots,i\} }[/math].
Variant: The pointer [math]\displaystyle{ p }[/math] is moved one step forward to the next array.
Break condition: It is sum [math]\displaystyle{ + p.n \ge\ell }[/math].
Induction basis
Abstract view: Set [math]\displaystyle{ p:= }[/math]first and sum[math]\displaystyle{ :=0 }[/math].
Implementation: Obvious.
Proof: Nothing to show.
Induction step
Abstract view: If the position [math]\displaystyle{ \ell }[/math] is in the current array, insert [math]\displaystyle{ K }[/math] (if the array is full, split it first).
Implementation:
- If [math]\displaystyle{ p= }[/math] void, terminate the algorithm and return false.
- If sum[math]\displaystyle{ + p.n \lt \ell }[/math]:
- Set sum[math]\displaystyle{ := }[/math]sum[math]\displaystyle{ + p.n }[/math].
- Set [math]\displaystyle{ p:=p }[/math].next.
- Otherwise:
- If [math]\displaystyle{ p.n=N }[/math]:
- Create a new array list item and let [math]\displaystyle{ p' }[/math] point to this new list item.
- Set [math]\displaystyle{ p' }[/math].next[math]\displaystyle{ =p }[/math].next.
- Set [math]\displaystyle{ p }[/math].next[math]\displaystyle{ :=p' }[/math].
- For [math]\displaystyle{ j \in \{1, \ldots, \lfloor p.n/2 \rfloor \} }[/math], set [math]\displaystyle{ p'.A[\lceil j \rceil]:=p.A[\lceil p.n/2 \rceil + j ] }[/math] and [math]\displaystyle{ p.A[\lceil p.n/2 \rceil + j]:= }[/math]void.
- Set [math]\displaystyle{ p'.n:=\lfloor p.n/2 \rfloor }[/math] and, afterwards, [math]\displaystyle{ p.n:=p.n - \lfloor p.n/2 \rfloor }[/math].
- If [math]\displaystyle{ l - }[/math]sum[math]\displaystyle{ \gt p.n }[/math]:
- Set [math]\displaystyle{ m:=l - }[/math] sum [math]\displaystyle{ - p.n + 1 }[/math].
- Set [math]\displaystyle{ p:=p' }[/math].
- Otherwise, set [math]\displaystyle{ m:=l - }[/math]sum[math]\displaystyle{ + 1 }[/math].
- For [math]\displaystyle{ j=p.n, \ldots, m }[/math] (in this order), set [math]\displaystyle{ p.A[j+1]:=p.A[j] }[/math].
- Set [math]\displaystyle{ p.A[m]:=K }[/math].
- If [math]\displaystyle{ p.n=N }[/math]:
- Return true.
Correctness: Note that, in an implementation of Ordered sequence: insert at position, we may assume [math]\displaystyle{ l \leq }[/math]number(). Therefore, we do not have to care about the end of the list. In the case sum[math]\displaystyle{ + p.n \lt l }[/math], we simply have to update sum and [math]\displaystyle{ p }[/math], which is obviously done correctly. So consider the case sum[math]\displaystyle{ + p.n \ge l }[/math], which means that the position where [math]\displaystyle{ K }[/math] has to be inserted is in the array list item to which [math]\displaystyle{ p }[/math] currently points. If that array is full, new space must be allocated. Step 2.1 does that and distributes the elements roughly equally over both items. Steps 2.2 - 2.3 ensure that [math]\displaystyle{ p }[/math] points to the array where to insert [math]\displaystyle{ K }[/math] and [math]\displaystyle{ m }[/math] identifies the correct insert position. Step 2.4 empties the array component where to insert the new element by moving, exactly one position forward, the value at the position and the values at all later position (which is possible because the array is not full in any case).
Complexity
Statement: Linear in the length of the sequence in the worst case.
Proof: Obvious.