Array list: insert at position

From Algowiki
Jump to: navigation, search

Algorithmic problem: Ordered sequence: insert at position

Type of algorithm: loop

Auxiliary data:

  1. 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.
  2. Two pointers, [math]p[/math] and [math]p'[/math], of type "pointer to array list item of type [math]\mathcal{K}[/math]".

Abstract view

Invariant:After [math]i \ge 0[/math] iterations:

  1. The pointer [math]p[/math] points to the array at position [math]i+1[/math] in the array list.
  2. 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\ell[/math].

Induction basis

Abstract view: Set [math]p:=[/math]first and sum[math]:=0[/math].

Implementation: Obvious.

Proof: Nothing to show.

Induction step

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:

  1. If [math]p=[/math] void, terminate the algorithm and return false.
  2. If sum[math]+ p.n \lt \ell[/math]:
    1. Set sum[math]:=[/math]sum[math]+ p.n[/math].
    2. Set [math]p:=p[/math].next.
  3. Otherwise:
    1. If [math]p.n=N[/math]:
      1. Create a new array list item and let [math]p'[/math] point to this new list item.
      2. Set [math]p'[/math].next[math]=p[/math].next.
      3. Set [math]p[/math].next[math]:=p'[/math].
      4. 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.
      5. Set [math]p'.n:=\lfloor p.n/2 \rfloor[/math] and, afterwards, [math]p.n:=p.n - \lfloor p.n/2 \rfloor[/math].
    2. If [math]l - [/math]sum[math] \gt p.n[/math]:
      1. Set [math]m:=l -[/math] sum [math] - p.n + 1[/math].
      2. Set [math]p:=p'[/math].
    3. Otherwise, set [math]m:=l -[/math]sum[math]+ 1[/math].
    4. For [math]j=p.n, \ldots, m[/math] (in this order), set [math]p.A[j+1]:=p.A[j][/math].
    5. Set [math]p.A[m]:=K[/math].
  4. Return true.

Correctness: Note that, in an implementation of 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 \lt 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

Statement: Linear in the length of the sequence in the worst case.

Proof: Obvious.

Further information