September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
|
|
@ -0,0 +1,57 @@
|
|||
BEGIN
|
||||
# returns the kth lowest element of list using the quick select algorithm #
|
||||
PRIO QSELECT = 1;
|
||||
OP QSELECT = ( INT k, REF[]INT list )INT:
|
||||
IF LWB list > UPB list THEN
|
||||
# empty list #
|
||||
0
|
||||
ELSE
|
||||
# non-empty list #
|
||||
# partitions the subset of list from left to right #
|
||||
PROC partition = ( REF[]INT list, INT left, right, pivot index )INT:
|
||||
BEGIN
|
||||
# swaps elements a and b in list #
|
||||
PROC swap = ( REF[]INT list, INT a, b )VOID:
|
||||
BEGIN
|
||||
INT t = list[ a ];
|
||||
list[ a ] := list[ b ];
|
||||
list[ b ] := t
|
||||
END # swap # ;
|
||||
INT pivot value = list[ pivot index ];
|
||||
swap( list, pivot index, right );
|
||||
INT store index := left;
|
||||
FOR i FROM left TO right - 1 DO
|
||||
IF list[ i ] < pivot value THEN
|
||||
swap( list, store index, i );
|
||||
store index +:= 1
|
||||
FI
|
||||
OD;
|
||||
swap( list, right, store index );
|
||||
store index
|
||||
END # partition # ;
|
||||
INT left := LWB list, right := UPB list, result := 0;
|
||||
BOOL found := FALSE;
|
||||
WHILE NOT found DO
|
||||
IF left = right THEN
|
||||
result := list[ left ];
|
||||
found := TRUE
|
||||
ELSE
|
||||
INT pivot index = partition( list, left, right, left + ENTIER ( ( random * ( right - left ) + 1 ) ) );
|
||||
IF k = pivot index THEN
|
||||
result := list[ k ];
|
||||
found := TRUE
|
||||
ELIF k < pivot index THEN
|
||||
right := pivot index - 1
|
||||
ELSE
|
||||
left := pivot index + 1
|
||||
FI
|
||||
FI
|
||||
OD;
|
||||
result
|
||||
FI # QSELECT # ;
|
||||
# test cases #
|
||||
FOR i TO 10 DO
|
||||
[ 1 : 10 ]INT test := []INT( 9, 8, 7, 6, 5, 0, 1, 2, 3, 4 );
|
||||
print( ( whole( i, -2 ), ": ", whole( i QSELECT test, -3 ), newline ) )
|
||||
OD
|
||||
END
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
// this just helps make partition read better
|
||||
function swap(items, firstIndex, secondIndex) {
|
||||
var temp = items[firstIndex];
|
||||
items[firstIndex] = items[secondIndex];
|
||||
items[secondIndex] = temp;
|
||||
};
|
||||
|
||||
// many algorithms on this page violate
|
||||
// the constraint that partition operates in place
|
||||
function partition(array, from, to) {
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
|
||||
var pivotIndex = getRandomInt(from, to),
|
||||
pivot = array[pivotIndex];
|
||||
swap(array, pivotIndex, to);
|
||||
pivotIndex = from;
|
||||
|
||||
for(var i = from; i <= to; i++) {
|
||||
if(array[i] < pivot) {
|
||||
swap(array, pivotIndex, i);
|
||||
pivotIndex++;
|
||||
}
|
||||
};
|
||||
swap(array, pivotIndex, to);
|
||||
|
||||
return pivotIndex;
|
||||
};
|
||||
|
||||
// later versions of JS have TCO so this is safe
|
||||
function quickselectRecursive(array, from, to, statistic) {
|
||||
if(array.length === 0 || statistic > array.length - 1) {
|
||||
return undefined;
|
||||
};
|
||||
|
||||
var pivotIndex = partition(array, from, to);
|
||||
if(pivotIndex === statistic) {
|
||||
return array[pivotIndex];
|
||||
} else if(pivotIndex < statistic) {
|
||||
return quickselectRecursive(array, pivotIndex, to, statistic);
|
||||
} else if(pivotIndex > statistic) {
|
||||
return quickselectRecursive(array, from, pivotIndex, statistic);
|
||||
}
|
||||
};
|
||||
|
||||
function quickselectIterative(array, k) {
|
||||
if(array.length === 0 || k > array.length - 1) {
|
||||
return undefined;
|
||||
};
|
||||
|
||||
var from = 0, to = array.length,
|
||||
pivotIndex = partition(array, from, to);
|
||||
|
||||
while(pivotIndex !== k) {
|
||||
pivotIndex = partition(array, from, to);
|
||||
if(pivotIndex < k) {
|
||||
from = pivotIndex;
|
||||
} else if(pivotIndex > k) {
|
||||
to = pivotIndex;
|
||||
}
|
||||
};
|
||||
|
||||
return array[pivotIndex];
|
||||
};
|
||||
|
||||
KthElement = {
|
||||
find: function(array, element) {
|
||||
var k = element - 1;
|
||||
return quickselectRecursive(array, 0, array.length, k);
|
||||
// you can also try out the Iterative version
|
||||
// return quickselectIterative(array, k);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
var array = [9, 8, 7, 6, 5, 0, 1, 2, 3, 4],
|
||||
ks = Array.apply(null, {length: 10}).map(Number.call, Number);
|
||||
ks.map(k => { KthElement.find(array, k) });
|
||||
|
|
@ -0,0 +1 @@
|
|||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
// QUICKSELECT ------------------------------------------------------------
|
||||
|
||||
// quickselect :: Ord a => Int -> [a] -> a
|
||||
const quickSelect = (k, xxs) => {
|
||||
const
|
||||
[x, xs] = uncons(xxs),
|
||||
[ys, zs] = partition(v => v < x, xs),
|
||||
l = length(ys);
|
||||
|
||||
return (k < l) ? (
|
||||
quickSelect(k, ys)
|
||||
) : (k > l) ? (
|
||||
quickSelect(k - l - 1, zs)
|
||||
) : x;
|
||||
};
|
||||
|
||||
|
||||
// GENERIC FUNCTIONS ------------------------------------------------------
|
||||
|
||||
// enumFromTo :: Int -> Int -> [Int]
|
||||
const enumFromTo = (m, n) =>
|
||||
Array.from({
|
||||
length: Math.floor(n - m) + 1
|
||||
}, (_, i) => m + i);
|
||||
|
||||
// length :: [a] -> Int
|
||||
const length = xs => xs.length;
|
||||
|
||||
// map :: (a -> b) -> [a] -> [b]
|
||||
const map = (f, xs) => xs.map(f);
|
||||
|
||||
// partition :: Predicate -> List -> (Matches, nonMatches)
|
||||
// partition :: (a -> Bool) -> [a] -> ([a], [a])
|
||||
const partition = (p, xs) =>
|
||||
xs.reduce((a, x) =>
|
||||
p(x) ? [a[0].concat(x), a[1]] : [a[0], a[1].concat(x)], [
|
||||
[],
|
||||
[]
|
||||
]);
|
||||
|
||||
// uncons :: [a] -> Maybe (a, [a])
|
||||
const uncons = xs => xs.length ? [xs[0], xs.slice(1)] : undefined;
|
||||
|
||||
|
||||
// TEST -------------------------------------------------------------------
|
||||
const v = [9, 8, 7, 6, 5, 0, 1, 2, 3, 4];
|
||||
|
||||
return map(i => quickSelect(i, v), enumFromTo(0, length(v) - 1));
|
||||
})();
|
||||
|
|
@ -0,0 +1 @@
|
|||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// version 1.1.2
|
||||
|
||||
const val MAX = Int.MAX_VALUE
|
||||
val rand = java.util.Random()
|
||||
|
||||
fun partition(list:IntArray, left: Int, right:Int, pivotIndex: Int): Int {
|
||||
val pivotValue = list[pivotIndex]
|
||||
list[pivotIndex] = list[right]
|
||||
list[right] = pivotValue
|
||||
var storeIndex = left
|
||||
for (i in left until right) {
|
||||
if (list[i] < pivotValue) {
|
||||
val tmp = list[storeIndex]
|
||||
list[storeIndex] = list[i]
|
||||
list[i] = tmp
|
||||
storeIndex++
|
||||
}
|
||||
}
|
||||
val temp = list[right]
|
||||
list[right] = list[storeIndex]
|
||||
list[storeIndex] = temp
|
||||
return storeIndex
|
||||
}
|
||||
|
||||
tailrec fun quickSelect(list: IntArray, left: Int, right: Int, k: Int): Int {
|
||||
if (left == right) return list[left]
|
||||
var pivotIndex = left + Math.floor((rand.nextInt(MAX) % (right - left + 1)).toDouble()).toInt()
|
||||
pivotIndex = partition(list, left, right, pivotIndex)
|
||||
if (k == pivotIndex)
|
||||
return list[k]
|
||||
else if (k < pivotIndex)
|
||||
return quickSelect(list, left, pivotIndex - 1, k)
|
||||
else
|
||||
return quickSelect(list, pivotIndex + 1, right, k)
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val list = intArrayOf(9, 8, 7, 6, 5, 0, 1, 2, 3, 4)
|
||||
val right = list.size - 1
|
||||
for (k in 0..9) {
|
||||
print(quickSelect(list, 0, right, k))
|
||||
if (k < 9) print(", ")
|
||||
}
|
||||
println()
|
||||
}
|
||||
30
Task/Quickselect-algorithm/PicoLisp/quickselect-algorithm.l
Normal file
30
Task/Quickselect-algorithm/PicoLisp/quickselect-algorithm.l
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
(seed (in "/dev/urandom" (rd 8)))
|
||||
(de swapL (Lst X Y)
|
||||
(let L (nth Lst Y)
|
||||
(swap
|
||||
L
|
||||
(swap (nth Lst X) (car L)) ) ) )
|
||||
(de partition (Lst L R P)
|
||||
(let V (get Lst P)
|
||||
(swapL Lst R P)
|
||||
(for I (range L R)
|
||||
(and
|
||||
(> V (get Lst I))
|
||||
(swapL Lst L I)
|
||||
(inc 'L) ) )
|
||||
(swapL Lst L R)
|
||||
L ) )
|
||||
(de quick (Lst N L R)
|
||||
(default L (inc N) R (length Lst))
|
||||
(if (= L R)
|
||||
(get Lst L)
|
||||
(let P (partition Lst L R (rand L R))
|
||||
(cond
|
||||
((= N P) (get Lst N))
|
||||
((> P N) (quick Lst N L P))
|
||||
(T (quick Lst N P R)) ) ) ) )
|
||||
(let Lst (9 8 7 6 5 0 1 2 3 4)
|
||||
(println
|
||||
(mapcar
|
||||
'((N) (quick Lst N))
|
||||
(range 0 9) ) ) )
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
/*REXX program sorts a list (which may be numbers) by using the quick select algorithm. */
|
||||
parse arg list; if list='' then list=9 8 7 6 5 0 1 2 3 4 /*Not given? Use default.*/
|
||||
say right('list: ', 22) list
|
||||
#=words(list)
|
||||
do i=1 for #; @.i=word(list, i) /*assign all the items ──► @. (array). */
|
||||
end /*i*/ /* [↑] #: number of items in the list.*/
|
||||
say
|
||||
do #=1 for words(list); @.#=word(list,#) /*assign all the items ──► @. (array). */
|
||||
end /*#*/ /* [↑] #: number of items in the list.*/
|
||||
#=#-1 /*adjust number of items in the list. */
|
||||
do j=1 for # /*show 1 ──► # items place and value.*/
|
||||
say right('item', 20) right(j, length(#))", value: " qSel(1, #, j)
|
||||
end /*j*/
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
/*REXX program sorts a list (which may be numbers) by using the quick select algorithm. */
|
||||
parse arg list; if list='' then list=9 8 7 6 5 0 1 2 3 4 /*Not given? Use default.*/
|
||||
say right('list: ', 22) list
|
||||
#=words(list)
|
||||
do i=1 for #; @.i=word(list, i) /*assign all the items ──► @. (array). */
|
||||
end /*i*/ /* [↑] #: number of items in the list.*/
|
||||
say
|
||||
do #=1 for words(list); @.#=word(list,#) /*assign all the items ──► @. (array). */
|
||||
end /*#*/ /* [↑] #: number of items in the list.*/
|
||||
#=#-1 /*adjust number of items in the list. */
|
||||
do j=1 for # /*show 1 ──► # items place and value.*/
|
||||
say right('item', 20) right(j, length(#))", value: " qSel(1, #, j)
|
||||
end /*j*/
|
||||
|
|
|
|||
23
Task/Quickselect-algorithm/Zkl/quickselect-algorithm-1.zkl
Normal file
23
Task/Quickselect-algorithm/Zkl/quickselect-algorithm-1.zkl
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
fcn qselect(list,nth){ // in place quick select
|
||||
fcn(list,left,right,nth){
|
||||
if (left==right) return(list[left]);
|
||||
pivotIndex:=(left+right)/2; // or median of first,middle,last
|
||||
|
||||
// partition
|
||||
pivot:=list[pivotIndex];
|
||||
list.swap(pivotIndex,right); // move pivot to end
|
||||
pivotIndex := left;
|
||||
i:=left; do(right-left){ // foreach i in ([left..right-1])
|
||||
if (list[i] < pivot){
|
||||
list.swap(i,pivotIndex);
|
||||
pivotIndex += 1;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
list.swap(pivotIndex,right); // move pivot to final place
|
||||
|
||||
if (nth==pivotIndex) return(list[nth]);
|
||||
if (nth<pivotIndex) return(self.fcn(list,left,pivotIndex-1,nth));
|
||||
return(self.fcn(list,pivotIndex+1,right,nth));
|
||||
}(list.copy(),0,list.len()-1,nth);
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
list:=T(10, 9, 8, 7, 6, 1, 2, 3, 4, 5);
|
||||
foreach nth in (list.len()){ println(nth,": ",qselect(list,nth)) }
|
||||
Loading…
Add table
Add a link
Reference in a new issue