2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,10 +1,28 @@
|
|||
{{Sorting Algorithm}}
|
||||
|
||||
The '''Comb Sort''' is a variant of the [[Bubble Sort]]. Like the [[Shell sort]], the Comb Sort increases the gap used in comparisons and exchanges (dividing the gap by <math>(1-e^{-\varphi})^{-1} \approx 1.247330950103979</math> works best, but 1.3 may be more practical). Some implementations use the insertion sort once the gap is less than a certain amount. See the [[wp:Comb sort|article on Wikipedia]].
|
||||
Variants:
|
||||
*Combsort11 makes sure the gap ends in (11, 8, 6, 4, 3, 2, 1), which is significantly faster than the other two possible endings
|
||||
*Combsort with different endings changes to a more efficient sort when the data is almost sorted (when the gap is small). Comb sort with a low gap isn't much better than the Bubble Sort.
|
||||
;Task:
|
||||
Implement a ''comb sort''.
|
||||
|
||||
|
||||
The '''Comb Sort''' is a variant of the [[Bubble Sort]].
|
||||
|
||||
Like the [[Shell sort]], the Comb Sort increases the gap used in comparisons and exchanges.
|
||||
|
||||
Dividing the gap by <big><math>(1-e^{-\varphi})^{-1} \approx 1.247330950103979</math> </big> works best, but <big> 1.3</big> may be more practical.
|
||||
|
||||
|
||||
Some implementations use the insertion sort once the gap is less than a certain amount.
|
||||
|
||||
|
||||
;Also see:
|
||||
* the Wikipedia article: [[wp:Comb sort|Comb sort]].
|
||||
|
||||
|
||||
Variants:
|
||||
* Combsort11 makes sure the gap ends in (11, 8, 6, 4, 3, 2, 1), which is significantly faster than the other two possible endings.
|
||||
* Combsort with different endings changes to a more efficient sort when the data is almost sorted (when the gap is small). Comb sort with a low gap isn't much better than the Bubble Sort.
|
||||
|
||||
<br>
|
||||
Pseudocode:
|
||||
'''function''' combsort('''array''' input)
|
||||
gap := input'''.size''' ''//initialize gap size''
|
||||
|
|
@ -28,3 +46,4 @@ Pseudocode:
|
|||
'''end loop'''
|
||||
'''end loop'''
|
||||
'''end function'''
|
||||
<br><br>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
* Comb sort 23/06/2016
|
||||
COMBSORT CSECT
|
||||
USING COMBSORT,R13 base register
|
||||
B 72(R15) skip savearea
|
||||
DC 17F'0' savearea
|
||||
STM R14,R12,12(R13) prolog
|
||||
ST R13,4(R15) "
|
||||
ST R15,8(R13) "
|
||||
LR R13,R15 "
|
||||
L R2,N n
|
||||
BCTR R2,0 n-1
|
||||
ST R2,GAP gap=n-1
|
||||
DO UNTIL=(CLC,GAP,EQ,=F'1',AND,CLI,SWAPS,EQ,X'00') repeat
|
||||
L R4,GAP gap |
|
||||
MH R4,=H'100' gap*100 |
|
||||
SRDA R4,32 . |
|
||||
D R4,=F'125' /125 |
|
||||
ST R5,GAP gap=int(gap/1.25) |
|
||||
IF CLC,GAP,LT,=F'1' if gap<1 then -----------+ |
|
||||
MVC GAP,=F'1' gap=1 | |
|
||||
ENDIF , end if <-----------------+ |
|
||||
MVI SWAPS,X'00' swaps=false |
|
||||
LA RI,1 i=1 |
|
||||
DO UNTIL=(C,R3,GT,N) do i=1 by 1 until i+gap>n ---+ |
|
||||
LR R7,RI i | |
|
||||
SLA R7,2 . | |
|
||||
LA R7,A-4(R7) r7=@a(i) | |
|
||||
LR R8,RI i | |
|
||||
A R8,GAP i+gap | |
|
||||
SLA R8,2 . | |
|
||||
LA R8,A-4(R8) r8=@a(i+gap) | |
|
||||
L R2,0(R7) temp=a(i) | |
|
||||
IF C,R2,GT,0(R8) if a(i)>a(i+gap) then ---+ | |
|
||||
MVC 0(4,R7),0(R8) a(i)=a(i+gap) | | |
|
||||
ST R2,0(R8) a(i+gap)=temp | | |
|
||||
MVI SWAPS,X'01' swaps=true | | |
|
||||
ENDIF , end if <-----------------+ | |
|
||||
LA RI,1(RI) i=i+1 | |
|
||||
LR R3,RI i | |
|
||||
A R3,GAP i+gap | |
|
||||
ENDDO , end do <---------------------+ |
|
||||
ENDDO , until gap=1 and not swaps <------+
|
||||
LA R3,PG pgi=0
|
||||
LA RI,1 i=1
|
||||
DO WHILE=(C,RI,LE,N) do i=1 to n -------+
|
||||
LR R1,RI i |
|
||||
SLA R1,2 . |
|
||||
L R2,A-4(R1) a(i) |
|
||||
XDECO R2,XDEC edit a(i) |
|
||||
MVC 0(4,R3),XDEC+8 output a(i) |
|
||||
LA R3,4(R3) pgi=pgi+4 |
|
||||
LA RI,1(RI) i=i+1 |
|
||||
ENDDO , end do <-----------+
|
||||
XPRNT PG,L'PG print buffer
|
||||
L R13,4(0,R13) epilog
|
||||
LM R14,R12,12(R13) "
|
||||
XR R15,R15 "
|
||||
BR R14 exit
|
||||
A DC F'4',F'65',F'2',F'-31',F'0',F'99',F'2',F'83',F'782',F'1'
|
||||
DC F'45',F'82',F'69',F'82',F'104',F'58',F'88',F'112',F'89',F'74'
|
||||
N DC A((N-A)/L'A) number of items of a
|
||||
GAP DS F gap
|
||||
SWAPS DS X flag for swaps
|
||||
PG DS CL80 output buffer
|
||||
XDEC DS CL12 temp for edit
|
||||
YREGS
|
||||
RI EQU 6 i
|
||||
END COMBSORT
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
defmodule Sort do
|
||||
def comb_sort([]), do: []
|
||||
def comb_sort(input) do
|
||||
comb_sort(List.to_tuple(input), length(input), 0) |> Tuple.to_list
|
||||
end
|
||||
|
||||
defp comb_sort(output, 1, 0), do: output
|
||||
defp comb_sort(input, gap, _) do
|
||||
gap = max(trunc(gap / 1.25), 1)
|
||||
{output,swaps} = Enum.reduce(0..tuple_size(input)-gap-1, {input,0}, fn i,{acc,swap} ->
|
||||
if (x = elem(acc,i)) > (y = elem(acc,i+gap)) do
|
||||
{acc |> put_elem(i,y) |> put_elem(i+gap,x), 1}
|
||||
else
|
||||
{acc,swap}
|
||||
end
|
||||
end)
|
||||
comb_sort(output, gap, swaps)
|
||||
end
|
||||
end
|
||||
|
||||
(for _ <- 1..20, do: :rand.uniform(20)) |> IO.inspect |> Sort.comb_sort |> IO.inspect
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
// Node 5.4.1 tested implementation (ES6)
|
||||
function is_array_sorted(arr) {
|
||||
var sorted = true;
|
||||
for (var i = 0; i < arr.length - 1; i++) {
|
||||
if (arr[i] > arr[i + 1]) {
|
||||
sorted = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sorted;
|
||||
}
|
||||
|
||||
// Array to sort
|
||||
var arr = [4, 9, 0, 3, 1, 5];
|
||||
|
||||
var iteration_count = 0;
|
||||
var gap = arr.length - 2;
|
||||
var decrease_factor = 1.25;
|
||||
|
||||
// Until array is not sorted, repeat iterations
|
||||
while (!is_array_sorted(arr)) {
|
||||
// If not first gap
|
||||
if (iteration_count > 0)
|
||||
// Calculate gap
|
||||
gap = (gap == 1) ? gap : Math.floor(gap / decrease_factor);
|
||||
|
||||
// Set front and back elements and increment to a gap
|
||||
var front = 0;
|
||||
var back = gap;
|
||||
while (back <= arr.length - 1) {
|
||||
// If elements are not ordered swap them
|
||||
if (arr[front] > arr[back]) {
|
||||
var temp = arr[front];
|
||||
arr[front] = arr[back];
|
||||
arr[back] = temp;
|
||||
}
|
||||
|
||||
// Increment and re-run swapping
|
||||
front += 1;
|
||||
back += 1;
|
||||
}
|
||||
iteration_count += 1;
|
||||
}
|
||||
|
||||
// Print the sorted array
|
||||
console.log(arr);
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
comb.sort<-function(a){
|
||||
gap<-length(a)
|
||||
swaps<-1
|
||||
while(gap>1 & swaps==1){
|
||||
gap=floor(gap/1.3)
|
||||
if(gap<1){
|
||||
gap=1
|
||||
}
|
||||
swaps=0
|
||||
i=1
|
||||
while(i+gap<=length(a)){
|
||||
if(a[i]>a[i+gap]){
|
||||
a[c(i,i+gap)] <- a[c(i+gap,i)]
|
||||
swaps=1
|
||||
}
|
||||
i<-i+1
|
||||
}
|
||||
}
|
||||
return(a)
|
||||
}
|
||||
|
|
@ -1,34 +1,34 @@
|
|||
/*REXX program sorts a stemmed array using the comb sort algorithm. */
|
||||
call gen; w=length(#) /*generate the @ array elements. */
|
||||
call show 'before sort' /*display the before array elements. */
|
||||
say copies('▒',60) /*display a separator line (a fence). */
|
||||
call combSort # /*invoke the comb sort. */
|
||||
call show ' after sort' /*display the after array elements. */
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────COMBSORT subroutine───────────────────────*/
|
||||
combSort: procedure expose @.; parse arg N /*N: is number of @ elements. */
|
||||
s=N-1 /*S: is the spread between COMBs.*/
|
||||
do until s<=1 & done; done=1 /*assume sort is done (so far). */
|
||||
s=trunc(s*.8) /* ÷ is slow, * is better.*/
|
||||
do j=1 until js>=N; js=j+s
|
||||
if @.j>@.js then do; _=@.j; @.j=@.js; @.js=_; done=0; end
|
||||
end /*j*/
|
||||
end /*until*/
|
||||
return
|
||||
/*──────────────────────────────────GEN subroutine────────────────────────────*/
|
||||
gen: @. = ; @.12 = 'dodecagon 12'
|
||||
@.1 = '----polygon--- sides' ; @.13 = 'tridecagon 13'
|
||||
@.2 = '============== =======' ; @.14 = 'tetradecagon 14'
|
||||
@.3 = 'triangle 3' ; @.15 = 'pentadecagon 15'
|
||||
@.4 = 'quadrilateral 4' ; @.16 = 'hexadecagon 16'
|
||||
@.5 = 'pentagon 5' ; @.17 = 'heptadecagon 17'
|
||||
@.6 = 'hexagon 6' ; @.18 = 'octadecagon 18'
|
||||
@.7 = 'heptagon 7' ; @.19 = 'enneadecagon 19'
|
||||
@.8 = 'octagon 8' ; @.20 = 'icosagon 20'
|
||||
@.9 = 'nonagon 9' ; @.21 = 'hectogon 100'
|
||||
@.10 = 'decagon 10' ; @.22 = 'chiliagon 1000'
|
||||
@.11 = 'hendecagon 11' ; @.23 = 'myriagon 10000'
|
||||
do #=1 while @.#\==''; end; #=#-1 /*determine how many entries in @ array*/
|
||||
return
|
||||
/*──────────────────────────────────SHOW subroutine───────────────────────────*/
|
||||
show: do j=1 for #; say ' element' right(j,w) arg(1)":" @.j; end; return
|
||||
/*REXX program sorts and displays a stemmed array using the comb sort algorithm. */
|
||||
call gen; w=length(#) /*generate the @ array elements. */
|
||||
call show 'before sort' /*display the before array elements. */
|
||||
say copies('▒', 60) /*display a separator line (a fence). */
|
||||
call combSort # /*invoke the comb sort (with # entries)*/
|
||||
call show ' after sort' /*display the after array elements. */
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
combSort: procedure expose @.; parse arg N /*N: is the number of @ elements. */
|
||||
s=N-1 /*S: is the spread between COMBs. */
|
||||
do until s<=1 & done; done=1 /*assume sort is done (so far). */
|
||||
s=trunc(s*0.8) /*Note: ÷ is slow, * is better.*/
|
||||
do j=1 until js>=N; js=j+s
|
||||
if @.j>@.js then do; _=@.j; @.j=@.js; @.js=_; done=0; end
|
||||
end /*j*/
|
||||
end /*until*/
|
||||
return
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
gen: @. = ; @.12 = "dodecagon 12"
|
||||
@.1 = '----polygon--- sides' ; @.13 = "tridecagon 13"
|
||||
@.2 = '============== =======' ; @.14 = "tetradecagon 14"
|
||||
@.3 = 'triangle 3' ; @.15 = "pentadecagon 15"
|
||||
@.4 = 'quadrilateral 4' ; @.16 = "hexadecagon 16"
|
||||
@.5 = 'pentagon 5' ; @.17 = "heptadecagon 17"
|
||||
@.6 = 'hexagon 6' ; @.18 = "octadecagon 18"
|
||||
@.7 = 'heptagon 7' ; @.19 = "enneadecagon 19"
|
||||
@.8 = 'octagon 8' ; @.20 = "icosagon 20"
|
||||
@.9 = 'nonagon 9' ; @.21 = "hectogon 100"
|
||||
@.10 = 'decagon 10' ; @.22 = "chiliagon 1000"
|
||||
@.11 = 'hendecagon 11' ; @.23 = "myriagon 10000"
|
||||
do #=1 while @.#\==''; end; #=#-1 /*find how many elements in @*/
|
||||
return /* [↑] adjust # because of the DO loop*/
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
show: do j=1 for #; say ' element' right(j,w) arg(1)":" @.j; end; return
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue