Problème 1.

Consider the following sequence of values

Note

We can represent tree textually via the following representation

13 (
	11 (
		8 (
			2
			4
		)
		12 (
			*
			1
		)
	)
	 7 (
		 5
		 6 (
			 99
			 *
		 )
	)
)

Where we use as a placeholder for a missing child for those nodes that only have a single child.

P1.1

Draw the min heap (as a tree) obtained by adding the values in in sequence. Show each step

  1. . The root of the heap.

    3
  2. . Added to the left of the root.

3 (
  42
  *
)
  1. . Added to the right of the root.
3 (
  42
  39
)
  1. . Added to the left of the left child of the root. (42 < 86)
3 (
  42 (
    86
    *
  )
  39
)
  1. . Added to the right of 42.
3 (
  42 (
    86
    49
  )
  39
)
  1. . Added to the left of 39.
3 (
  42 (
    86
    49
  )
  39 (
    89
  )
)
  1. . Added to the right of 39.
3 (
  42 (
    86
    49
  )
  39 (
    89
    99
  )
)
  1. . 20 becomes left child of 86. (20 < 86) then swap. (20 < 42) then swap.
3 (
  20 (
    42
      (
        86
        *
      )
    49
  )
  39 (
    89
    99
  )
)
  1. . 88 becomes right of 42
3 (
  20 (
    42 (
      86
      88
    )
    49
  )
  39 (
    89
    99
  )
)
  1. . 51 becomes right of 49
3 (
  20 (
    42 (
      86
      88
    )
    49 (
      51
      *
    )
  )
  39 (
    89
    99
  )
)
  1. . 64 becomes right of 49
3 (
  20 (
    42 (
      86
      88
    )
    49 (
      51
      64
    )
  )
  39 (
    89
    99
  )
)

P1.2

Draw the max heap (as a tree) obtained by adding the values in in sequence. Show each step

  1. . The root of the heap.
    3
  2. . 42 becomes the root, 3 becomes left child.
42 (
  3
  *
)
  1. . 39 becomes right child.
42 (
  3
  39
)
  1. . 86 becomes root. 42 becomes left child, 3 becomes left child of 42.
86 (
  42 (
    3
    *
  )
  39
)
  1. . 49 becomes left child of 86, swap 42, 42 becomes right child of 49.
86 (
  49 (
    3
    42
  )
  39
)
  1. . 89 become routes, swap 86, 49.
89 (
  49 (
    3
    42
  )
  86 (
    39
    *
  )
)
  1. . 99 becomes root, swap 89, 49.
99 (
  49 (
    3
    42
  )
  89 (
    39
    86
  )
)
  1. . 20 swap with 3, 3 becomes left child of 20.
99 (
  49 (
    20 (
      3
      *
    )
    42
    )
  89 (
    39
    86
  )
)
  1. . 88 becomes left child of 99, swap 49, 20.
99 (
  88 (
    49 (
      20 (
        3
        *
      )
      *
    )
    42
  )
  89 (
    39
    86
  )
)
  1. . 51 becomes right child of 88, swap 42, 20.
99 (
  88 (
    51 (
      42 (
        20 (
          3
          *
        )
      )
      *
    )
    49
  )
  89 (
    39
    86
  )
)
  1. . 64, pushes 49 down.
99 (
  88 (
    51 (
      42 (
        20 (
          3
          *
        )
      )
      *
    )
    64 (
      49
      *
    )
  )
  89 (
    39
    86
  )
)

P1.3

Draw the binary search tree obtained by adding the values in in sequence. Show each step

  1. . The root of the tree.

    3
  2. . 42 becomes the right child of 3.

3 (
  *
  42
)
  1. . 39 becomes the left child of 42.
3 (
  *
  42 (
    39
    *
  )
)
  1. . 86 becomes the right child of 42.
3 (
  *
  42 (
    39
    86
  )
)
  1. . 49 becomes the left child of 86.
3 (
  *
  42 (
    39
    86 (
      49
      *
    )
  )
)
  1. . 89 becomes the right child of 86.
3 (
  *
  42 (
    39
    86 (
      49
      89
    )
  )
)
  1. . 99 becomes the right child of 89.
3 (
  *
  42 (
    39
    86 (
      49
      89 (
        *
        99
      )
    )
  )
)
  1. . 20 becomes the left child of 39.
3 (
  *
  42 (
    39 (
      20
      *
    )
    86 (
      49
      89 (
        *
        99
      )
    )
  )
)
  1. . 88 becomes the right child of 86.
3 (
  *
  42 (
    39 (
      20
      *
    )
    86 (
      49
      89 (
        88
        99
      )
    )
  )
)
  1. . 51 becomes the right child of 49.
3 (
  *
  42 (
    39 (
      20
      *
    )
    86 (
      49 (
        *
        51
      )
      89 (
        88
        99
      )
    )
  )
)
  1. . 64 becomes the left child of 51.
3 (
  *
  42 (
  	39 (
  		20
  		*
  	)
  	86 (
  		49 (
  			*
  			51 (
  				*
  				64
  			)
  		)
  		89 (
  			88
  			99
  		)
  	)
  )
)

Problème 2.

Given an ordered list and value , the LowerBound algorithm provide the position in list such that is the first offset in of a value larger-equal to . Hence, (or, if no such offset exists, ). The LowerBound algorithm does so in comparisons. Argue that LowerBound is worst-case optimal: any algorithm that finds the correct position for any inputs and using only comparisons will require comparisons.

Solution

For a list of size there are possible outcomes for the position in the list. The minimum height of a binary tree needed for outcomes is (at most leaves or

From Stirling’s approximation, comparison-based sorting algorithm lower bound is . Given that the algorithm operates in comparisons, it matches with the theoretical lower bound for the search algorithm. Therefore, no comparison-based algorithm can guarantee a better worst-case performance for position , making LowerBound the worst-case optimal.

Problème 3.

Min heaps and max heaps allow one to efficiently store values and efficiently look up and remove the smallest values and largest values, respectively. One cannot easily remove the largest value from a min heap or the smallest value from a max heap, however.

P3.1

Assume a value is a part of a min heap of at-most values and that we know v is stored at position in that heap. Provide an algorithm that can remove from the heap in worst-case

Algorithm 23 RemoveValue(heap,pheap, p)

1:procedure RemoveValue(heap,iheap, i)

2:nheap.lengthn \gets heap.length

3:tempheap[p]temp \gets heap[p]

4:heap[p]heap[n]heap[p] \gets heap[n]

5:heap[n]tempheap[n] \gets temp

6:heapheap[:n]heap \gets heap[:n]

7:HeapifyDown(heap,p)\text{HeapifyDown}(heap, p)

8:end procedure

Algorithm 24 HeapifyDown(heap,pheap, p)

1:procedure HeapifyDown(heap,iheap, i)

2:nsize of heapn \gets \text{size of } heap

3:while lchild(i)n\text{lchild}(i) \leq n do

4:leftlchild(i)\text{left} \gets \text{lchild}(i)

5:rightrchild(i)\text{right} \gets \text{rchild}(i)

6:smallesti\text{smallest} \gets i

7:if leftn and heap[left]<heap[smallest]\text{left} \leq n \text{ and } heap[\text{left}] < heap[\text{smallest}] then

8:smallestleft\text{smallest} \gets \text{left}

9:end if

10:if rightn and heap[right]<heap[smallest]\text{right} \leq n \text{ and } heap[\text{right}] < heap[\text{smallest}] then

11:smallestright\text{smallest} \gets \text{right}

12:end if

13:if smallest=i\text{smallest} = i then

14:break

15:else

16:Swap heap[i] with heap[smallest]\text{Swap } heap[i] \text{ with } heap[\text{smallest}]

17:ismallesti \gets \text{smallest}

18:end if

19:end while

20:end procedure

P3.2

Provide a data structure that allows one to efficiently store values and efficiently look up and remove both the smallest and the largest values: all three of these operations should be supported in

We will implement a Double-ended Priority Queue (DEPQ), which is a min-max heap.

Algorithm 25 Insert(heap,vheap, v)

1:procedure Insert(heap,vheap, v)

2:heap.push(v)heap.push(v)

3:Swim(heap,size(heap))\text{Swim}(heap, \text{size}(heap))

4:end procedure

Algorithm 26 RemoveMin(heapheap)

1:procedure RemoveMin(heapheap)

2:nsize(heap)n \gets \text{size}(heap)

3:tempheap[1]temp \gets heap[1]

4:heap[1]heap[size(heap)]heap[1] \gets heap[\text{size}(heap)]

5:heap[n]tempheap[n] \gets temp

6:heapheap[:n]heap \gets heap[:n]

7:Sink(heap,1)\text{Sink}(heap, 1)

8:end procedure

Algorithm 27 RemoveMax(heapheap)

1:procedure RemoveMax(heapheap)

2:maxPosargmax{heap[2],heap[3]}maxPos \gets \text{argmax}\{heap[2], heap[3]\}

3:heap[maxPos]heap[size(heap)]heap[maxPos] \gets heap[\text{size}(heap)]

4:remove last el fromheap\text{remove last el from} heap

5:Sink(heap,maxPos)\text{Sink}(heap, maxPos)

6:end procedure

Algorithm 28 Swim(heap,iheap, i)

1:procedure Swim(heap,iheap, i)

2:while i>1i > 1 do

3:parenti/2parent \gets \lfloor i/2 \rfloor

4:grandParentparent/2grandParent \gets \lfloor parent/2 \rfloor

5:if (imod2=0 and heap[i]<heap[parent]) or (imod20 and heap[i]>heap[parent])(i \mod 2 = 0 \text{ and } heap[i] < heap[parent]) \text{ or } (i \mod 2 \neq 0 \text{ and } heap[i] > heap[parent]) then

6:Swap(heap[i],heap[parent])\text{Swap}(heap[i], heap[parent])

7:end if

8:if grandParent1 and (heap[i]<heap[grandParent] or heap[i]>heap[grandParent])grandParent \geq 1 \text{ and } (heap[i] < heap[grandParent] \text{ or } heap[i] > heap[grandParent]) then

9:Swap(heap[i],heap[grandParent])\text{Swap}(heap[i], heap[grandParent])

10:end if

11:iparenti \gets parent

12:end while

13:end procedure

Algorithm 29 Sink(heap,iheap, i)

1:procedure Sink(heap,iheap, i)

2:nsize(heap)n \gets \text{size}(heap)

3:while lchild(i)n\text{lchild}(i) \leq n do

4:leftlchild(i)left \gets \text{lchild}(i)

5:rightrchild(i)right \gets \text{rchild}(i)

6:targetitarget \gets i

7:if on min level and heap[left]<heap[target]\text{on min level and } heap[left] < heap[target] then

8:targetlefttarget \gets left

9:else if on max level and heap[left]>heap[target]\text{on max level and } heap[left] > heap[target] then

10:targetlefttarget \gets left

11:end if

12:if rightsize(heap)right \leq \text{size}(heap) then

13:if on min level and heap[right]<heap[target]\text{on min level and } heap[right] < heap[target] then

14:targetrighttarget \gets right

15:else if on max level and heap[right]>heap[target]\text{on max level and } heap[right] > heap[target] then

16:targetrighttarget \gets right

17:end if

18:end if

19:if target=itarget = i then

20:break

21:else

22:Swap(heap[i],heap[target])\text{Swap}(heap[i], heap[target])

23:itargeti \gets target

24:end if

25:end while

26:end procedure