Just another update

This commit is contained in:
Ingy döt Net 2015-02-20 00:35:01 -05:00
parent a25938f123
commit 00a190b0a6
6591 changed files with 94363 additions and 23227 deletions

View file

@ -1,4 +1,9 @@
{{Sorting Algorithm}}{{wikipedia|Heapsort}}[[wp:Heapsort|Heapsort]] is an in-place sorting algorithm with worst case and average complexity of <span style="font-family: serif">O(''n''log''n'')</span>. The basic idea is to turn the array into a binary heap structure, which has the property that it allows efficient retrieval and removal of the maximal element. We repeatedly "remove" the maximal element from the heap, thus building the sorted list from back to front. Heapsort requires random access, so can only be used on an array-like data structure.
{{Sorting Algorithm}} {{wikipedia|Heapsort}}
{{omit from|GUISS}}
[[wp:Heapsort|Heapsort]] is an in-place sorting algorithm with worst case and average complexity of <span style="font-family: serif">O(''n''log''n'')</span>.
The basic idea is to turn the array into a binary heap structure, which has the property that it allows efficient retrieval and removal of the maximal element.
We repeatedly "remove" the maximal element from the heap, thus building the sorted list from back to front.
Heapsort requires random access, so can only be used on an array-like data structure.
Pseudocode:
'''function''' heapSort(a, count) '''is'''

View file

@ -0,0 +1,16 @@
#include <algorithm>
#include <iterator>
#include <iostream>
template<typename RandomAccessIterator>
void heap_sort(RandomAccessIterator begin, RandomAccessIterator end) {
std::make_heap(begin, end);
std::sort_heap(begin, end);
}
int main() {
int a[] = {100, 2, 56, 200, -52, 3, 99, 33, 177, -199};
heap_sort(std::begin(a), std::end(a));
copy(std::begin(a), std::end(a), std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n";
}

View file

@ -1,6 +1,6 @@
import std.stdio, std.container;
void heapSort(T)(T[] data) /*pure nothrow*/ {
void heapSort(T)(T[] data) /*pure nothrow @safe @nogc*/ {
for (auto h = data.heapify; !h.empty; h.removeFront) {}
}

View file

@ -1,8 +1,8 @@
import std.stdio, std.algorithm;
void inplaceHeapSort(R)(R seq) pure nothrow {
void heapSort(R)(R seq) pure nothrow @safe @nogc {
static void siftDown(R seq, in size_t start,
in size_t end) pure nothrow {
in size_t end) pure nothrow @safe @nogc {
for (size_t root = start; root * 2 + 1 <= end; ) {
auto child = root * 2 + 1;
if (child + 1 <= end && seq[child] < seq[child + 1])
@ -16,17 +16,17 @@ void inplaceHeapSort(R)(R seq) pure nothrow {
}
if (seq.length > 1)
foreach_reverse (start; 1 .. (seq.length - 2) / 2 + 2)
foreach_reverse (immutable start; 1 .. (seq.length - 2) / 2 + 2)
siftDown(seq, start - 1, seq.length - 1);
foreach_reverse (end; 1 .. seq.length) {
foreach_reverse (immutable end; 1 .. seq.length) {
swap(seq[end], seq[0]);
siftDown(seq, 0, end - 1);
}
}
void main() {
auto arr = [7, 6, 5, 9, 8, 4, 3, 1, 2, 0];
inplaceHeapSort(arr);
writeln(arr);
auto data = [7, 6, 5, 9, 8, 4, 3, 1, 2, 0];
data.heapSort;
data.writeln;
}

View file

@ -0,0 +1,83 @@
\ Written in ANS-Forth; tested under VFX.
\ Requires the novice package: http://www.forth.org/novice.html
\ The following should already be done:
\ include novice.4th
\ This is already in the novice package, so it is not really necessary to compile the code provided here.
\ ******
\ ****** This is our array sort. We are using the heap-sort because it provides consistent times and it is not recursive.
\ ****** This code was ported from C++ at: http://www.snippets.24bytes.com/2010/06/heap-sort.html
\ ****** Our array record size must be a multiple of W. This is assured if FIELD is used for creating the record.
\ ****** The easiest way to speed this up is to rewrite EXCHANGE in assembly language.
\ ******
marker HeapSort.4th
macro: exchange ( adrX adrY size -- ) \ the size of the record must be a multiple of W
begin dup while \ -- adrX adrY remaining
over @ fourth @ \ -- adrX adrY remaining Y X
fourth ! fourth ! \ -- adrX adrY remaining
rot w + rot w + rot w -
repeat
3drop ;
\ All of these macros use the locals from SORT, and can only be called from SORT.
macro: adr ( index -- adr )
recsiz * array + ;
macro: left ( x -- y ) 2* 1+ ;
macro: right ( x -- y ) 2* 2 + ;
macro: heapify ( x -- )
dup >r begin \ r: -- great
dup left dup limit < if dup adr rover adr 'comparer execute if rdrop dup >r then then drop
dup right dup limit < if dup adr r@ adr 'comparer execute if rdrop dup >r then then drop
dup r@ <> while
adr r@ adr recsiz exchange
r@ repeat
drop rdrop ;
macro: build-max-heap ( -- )
limit 1- 2/ begin dup 0>= while dup heapify 1- repeat drop ;
: sort { array limit recsiz 'comparer -- }
recsiz [ w 1- ] literal and abort" *** SORT: record size must be a multiple of the cell size ***"
build-max-heap
begin limit while -1 +to limit
0 adr limit adr recsiz exchange
0 heapify repeat ;
\ The SORT locals:
\ array \ the address of the 0th element
\ limit \ the number of records in the array
\ recsiz \ the size of a record in the array \ this must be a multiple of W (FIELD assures this)
\ 'comparer \ adrX adrY -- X>Y?
\ Note for the novice:
\ This code was originally written with colon words rather than macros, and using items rather than local variables.
\ After it was debugged, it was changed to use macros and locals so that it would be fast and reentrant.
\ One of the reasons why the heap-sort was chosen is because it is not recursive, which allows macros to be used.
\ Using macros allows the data (array, limit, recsiz, 'comparer) to be held in locals rather than items, which is reentrant.
\ ******
\ ****** This tests SORT.
\ ******
create aaa 2 , 9 , 3 , 6 , 1 , 4 , 5 , 7 , 0 , 8 ,
: print-aaa ( limit -- )
cells aaa + aaa do I @ . w +loop ;
: int> ( adrX adrY -- X>Y? )
swap @ swap @ > ;
: test-sort ( limit -- )
cr dup print-aaa
aaa over w ['] int> sort
cr print-aaa ;
10 test-sort

View file

@ -0,0 +1,43 @@
fn heapify arr count =
(
local s = count /2
while s > 0 do
(
arr = siftDown arr s count
s -= 1
)
return arr
)
fn siftDown arr s end =
(
local root = s
while root * 2 <= end do
(
local child = root * 2
if child < end and arr[child] < arr[child+1] do
(
child += 1
)
if arr[root] < arr[child] then
(
swap arr[root] arr[child]
root = child
)
else return arr
)
return arr
)
fn heapSort arr =
(
local count = arr.count
arr = heapify arr count
local end = count
while end >= 1 do
(
swap arr[1] arr[end]
end -= 1
arr = siftDown arr 1 end
)
)

View file

@ -0,0 +1,4 @@
a = for i in 1 to 10 collect random 0 9
#(7, 2, 5, 6, 1, 5, 4, 0, 1, 6)
heapSort a
#(0, 1, 1, 2, 4, 5, 5, 6, 6, 7)

View file

@ -1,44 +1,42 @@
/*REXX program sorts an array using the heapsort method. */
/*REXX program sorts an array using the heapsort algorithm. */
call gen@ /*generate the array elements. */
call show@ 'before sort' /*show the before array elements*/
call heapSort highItem /*invoke the heap sort. */
call show@ ' after sort' /*show tge after array elements*/
call show@ 'before sort' /*show the before array elements*/
call heapSort # /*invoke the heap sort. */
call show@ ' after sort' /*show the after array elements*/
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────HEAPSORT subroutine─────────────────*/
heapSort: procedure expose @.; parse arg n; do j=n%2 by -1 to 1
call shuffle j,n
call shuffle j,n
end /*j*/
do n=n by -1 to 2
_=@.1; @.1=@.n; @.n=_; call shuffle 1,n-1 /*swap and shuffle.*/
end /*n*/
return
/*──────────────────────────────────SHUFFLE subroutine──────────────────*/
shuffle: procedure expose @.; parse arg i,n; _=@.i
shuffle: procedure expose @.; parse arg i,n; _=@.i
do while i+i<=n; j=i+i; k=j+1
if k<=n then if @.k>@.j then j=k
if _>=@.j then leave
@.i=@.j; i=j
end /*while i+i≤n*/
if _>=@.j then leave
@.i=@.j; i=j
end /*while*/
@.i=_
return
/*──────────────────────────────────GEN@ subroutine─────────────────────*/
gen@: @.= /*assign default value for array.*/
@.1 = '---modern Greek alphabet letters---'
@.2 = copies('=', length(@.1))
@.3 = 'alpha' ; @.11 = 'iota' ; @.19 = 'rho'
@.4 = 'beta' ; @.12 = 'kappa' ; @.20 = 'sigma'
@.5 = 'gamma' ; @.13 = 'lambda' ; @.21 = 'tau'
@.6 = 'delta' ; @.14 = 'mu' ; @.22 = 'upsilon'
@.7 = 'epsilon' ; @.15 = 'nu' ; @.23 = 'phi'
@.8 = 'zeta' ; @.16 = 'xi' ; @.24 = 'chi'
@.9 = 'eta' ; @.17 = 'omicron' ; @.25 = 'psi'
@.10 = 'theta' ; @.18 = 'pi' ; @.26 = 'omega'
do highItem=1 while @.highItem\==''; end /*find how many entries. */
highItem=highItem-1 /*adjust highItem slightly. */
gen@: @.=; @.1='---modern Greek alphabet letters---' /*default; title.*/
@.2= copies('=', length(@.1)) /*match sep with ↑*/
@.3='alpha' ; @.9 ='eta' ; @.15='nu' ; @.21='tau'
@.4='beta' ; @.10='theta' ; @.16='xi' ; @.22='upsilon'
@.5='gamma' ; @.11='iota' ; @.17='omicron' ; @.23='phi'
@.6='delta' ; @.12='kappa' ; @.18='pi' ; @.24='chi'
@.7='epsilon' ; @.13='lambd' ; @.19='rho' ; @.25='psi'
@.8='zeta' ; @.14='mu' ; @.20='sigma' ; @.26='omega'
do #=1 while @.#\==''; end /*find how many entries in list. */
#=#-1 /*adjust highItem slightly. */
return
/*──────────────────────────────────SHOW@ subroutine────────────────────*/
show@: do j=1 for highItem
say 'element' right(j,length(highItem)) arg(1)':' @.j
show@: do j=1 for # /* [↓] display elements in array.*/
say ' element' right(j,length(#)) arg(1)':' @.j
end /*j*/
say copies('', 79) /*show a separator line. */
say copies('', 70) /*show a separator line. */
return

View file

@ -0,0 +1,54 @@
(* Pairing heap - http://en.wikipedia.org/wiki/Pairing_heap *)
functor PairingHeap(type t
val cmp : t * t -> order) =
struct
datatype 'a heap = Empty
| Heap of 'a * 'a heap list;
(* merge, O(1)
* Merges two heaps *)
fun merge (Empty, h) = h
| merge (h, Empty) = h
| merge (h1 as Heap(e1, s1), h2 as Heap(e2, s2)) =
case cmp (e1, e2) of LESS => Heap(e1, h2 :: s1)
| _ => Heap(e2, h1 :: s2)
(* insert, O(1)
* Inserts an element into the heap *)
fun insert (e, h) = merge (Heap (e, []), h)
(* findMin, O(1)
* Returns the smallest element of the heap *)
fun findMin Empty = raise Domain
| findMin (Heap(e, _)) = e
(* deleteMin, O(lg n) amortized
* Deletes the smallest element of the heap *)
local
fun mergePairs [] = Empty
| mergePairs [h] = h
| mergePairs (h1::h2::hs) = merge (merge(h1, h2), mergePairs hs)
in
fun deleteMin Empty = raise Domain
| deleteMin (Heap(_, s)) = mergePairs s
end
(* build, O(n)
* Builds a heap from a list *)
fun build es = foldl insert Empty es;
end
local
structure IntHeap = PairingHeap(type t = int; val cmp = Int.compare);
open IntHeap
fun heapsort' Empty = []
| heapsort' h = findMin h :: (heapsort' o deleteMin) h;
in
fun heapsort ls = (heapsort' o build) ls
val test_0 = heapsort [] = []
val test_1 = heapsort [1,2,3] = [1, 2, 3]
val test_2 = heapsort [1,3,2] = [1, 2, 3]
val test_3 = heapsort [6,2,7,5,8,1,3,4] = [1, 2, 3, 4, 5, 6, 7, 8]
end;