FindMax (List, upper, lower)
{ Find the index of the largest of List[lower, upper];
upper >= lower > 0 }
max = lower
for index = lower+1 to upper
if List[index] > List[max] then
max = index
return max
FindSecondBest(List, lower, upper)
{Find the index of the second largest of List[lower..upper]
Break the list into 2 and find the largest of each half, then
find the largest of the candidates for second largest.}
mid = (lower+upper)/2
index1 = FindMax(List, lower, mid)
index2 = FindMax(List, mid+1, upper)
if List[index1] > List[index2] then
List[index1] = List[index2]
return FindMax(List, lower, mid)
else
List[index2] = List[index1]
return FindMax(List, mid+1, upper)
Is ceil[3n/2]-1 optimal? ---- break the first part into quarters: ceil[5n/4]-1...
A height m binomial tree is
BuildBinomialTree(List, lower, upper)
{Build a binomial tree on List[lower..upper], upper - lower + 1 is
a power of two. upper >= lower > 0 }
if upper > lower then
mid = (lower + upper) / 2
BuildBinomialTree(List, lower, mid)
BuildBinomialTree(List, mid+1, upper)
if List[mid] > List[upper] then
List[lower..mid] >==< List[mid+1..upper]
BuildBinomialTree has worst number of comparisons = 2lg n - 1 = n-1
Could build binomial tree using pointers but requires more space (two pointers for each node)
FindSecondMax(List, lower, upper)
{Find the index of the second largest of List[lower..upper].
Rearrange List to form a binomial tree, then find the largest of the
candidates. upper-lower+1 is power of 2. upper > lower > 0 }
BuildBinomialTree(List, lower, upper)
2max = upper - 1
for i = 1 to lg(upper-lower+1) - 1
if List[upper-2i] > List[2max] then
2max = upper -2i
return 2max
FindSecondMax does up to (n lg n) / 2 swaps
first phase does n - 1 comparisons
second phase does lg n - 1 comparisons
Is n + lg n - 2 optimal?
FindMaxMin(List, lower, upper)
{Find the indicies of the largest and smallest of List[lower..upper]
upper >= lower > 0 }
case upper - lower + 1
= 1 : return lower, lower
= 2 : if List[lower] > List[upper] then
return lower, upper
else
return upper, lower
> 2 :
mid = (lower+upper)/2
max1, min1 = FindMaxMin(List, lower, mid)
max2, min2 = FindMaxMin(List, mid+1, upper)
if List[max1] > List[max2] then
max = max1
else
max = max2
if List[min1] > List[min2] then
min = min2
else
min = min1
return max, min
FindMaxMin(List, lower, upper)
{Find the indicies of the largest and smallest of List[lower..upper]
upper >= lower > 0 }
case upper - lower + 1
= 1 : return lower, lower
= 2 : if List[lower] > List[upper] then
return lower, upper
else
return upper, lower
> 2 :
if List[lower] > List[lower+1] then
max1 = lower; min1 = lower+1
else
max1 = lower+1; min1 = lower
max2, min2 = FindMaxMin(List, lower+2, upper)
if List[max1] > List[max2] then
max = max1
else
max = max2
if List[min1] > List[min2] then
min = min2
else
min = min1
return max, min
Split(List, lower, upper, pivot-loc)
{Split List[lower..upper] into two parts, those less than List[pivot-loc]
on the left and those greater than it on the right. Return the pivot's
new position. upper >= pivot-loc >= lower > 0}
pivot = List[pivot-loc]
List[lower] <=> List[pivot-loc]
pivot-loc = lower
for index = lower+1 to upper
if pivot > List[index] then
pivot-loc++
List[index] <=> List[pivot-loc]
List[lower] <=> List[pivot-loc]
return pivot-loc
Find(List, lower, upper, i)
{Find the index of the ith largest of List[lower..upper]
upper >= lower > 0; upper - lower + 1 >= i >= 1 }
index = uniform(lower, upper)
pivot-loc = Split(List, lower, upper, index)
case upper - pivot-loc
< i-1: Find(List, lower, pivot-loc - 1, i-upper+ pivot-loc - 1)
= i-1: return pivot-loc
> i-1: Find(List, pivot-loc + 1, upper, i)
Select(List, lower, upper, i)
{Find the index of the ith largest of List[lower..upper].
Use the list Medians[1..ceil[n/5]] as extra storage.
upper >= lower > 0; upper - lower + 1 >= i >= 1 }
n = upper - lower + 1
for j = 0 to ceil[n/5] - 1
Medians[j+1] = median of List[(lower+5j)..(lower+5j+4)]
if n is not a multiple of 5 then
Medians[ceil[n/5]] = median of the remaining elements of List
index = Select(Medians, 1, ceil[n/5], ceil[n/10])
Make index the index of the corresponding element of List
pivot-loc = Split(List, lower, upper, index)
case upper - pivot-loc
< i-1: Select(List, lower, pivot-loc - 1, i - upper + pivot-loc -1_
= i-1: return pivot-loc
> i-1: Select(List, pivot-loc + 1, upper, i)