Sorting algorithms/Cocktail sort: Difference between revisions

added RPL
(added RPL)
(148 intermediate revisions by 62 users not shown)
Line 1:
{{task|Sorting Algorithms}}{{Sorting Algorithm}}{{wikipedia|Cocktail sort}}
{{Sorting Algorithm}}
The cocktail shaker sort is an improvement on the [[Bubble Sort]]. The improvement is basically that values "bubble" both directions through the array, because on each iteration the cocktail shaker sort bubble sorts once forwards and once backwards. Pseudocode for the algorithm (from [[wp:Cocktail sort|wikipedia]]):
[[Category:Sorting]]
{{Wikipedia|Cocktail sort}}
 
 
The cocktail shaker sort is an improvement on the [[Bubble Sort]].
 
The improvement is basically that values "bubble" both directions through the array, because on each iteration the cocktail shaker sort bubble sorts once forwards and once backwards. Pseudocode for the algorithm (from [[wp:Cocktail sort|wikipedia]]):
'''function''' ''cocktailSort''( A : list of sortable items )
'''do'''
Line 21 ⟶ 28:
'''while''' swapped; ''// if no elements have been swapped,''
''// then the list is sorted''
 
;Related task:
:*   [https://rosettacode.org/wiki/Sorting_algorithms/Cocktail_sort_with_shifting_bounds cocktail sort with shifting bounds]
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">F cocktailSort(&A)
L
L(indices) ((0 .< A.len-1).step(1), (A.len-2 .. 0).step(-1))
V swapped = 0B
L(i) indices
I A[i] > A[i + 1]
swap(&A[i], &A[i + 1])
swapped = 1B
I !swapped
R
 
V test1 = [7, 6, 5, 9, 8, 4, 3, 1, 2, 0]
cocktailSort(&test1)
print(test1)</syntaxhighlight>
 
{{out}}
<pre>
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
</pre>
 
=={{header|360 Assembly}}==
{{trans|PL/I}}
The program uses HLASM structured macros (DO,ENDDO,IF,ELSE,ENDIF) for readability and two ASSIST/360 macros (XDECO,XPRNT) to keep the code as short as possible.
<syntaxhighlight lang="360asm">* Cocktail sort 25/06/2016
COCKTSRT CSECT
USING COCKTSRT,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,NM1 nm1=n-1
DO UNTIL=(CLI,STABLE,EQ,X'01') repeat
MVI STABLE,X'01' stable=true
LA RI,1 i=1
DO WHILE=(C,RI,LE,NM1) do i=1 to n-1
LR R1,RI i
SLA R1,2 .
LA R2,A-4(R1) @a(i)
LA R3,A(R1) @a(i+1)
L R4,0(R2) r4=a(i)
L R5,0(R3) r5=a(i+1)
IF CR,R4,GT,R5 THEN if a(i)>a(i+1) then
MVI STABLE,X'00' stable=false
ST R5,0(R2) a(i)=r5
ST R4,0(R3) a(i+1)=r4
ENDIF , end if
LA RI,1(RI) i=i+1
ENDDO , end do
L RI,NM1 i=n-1
DO WHILE=(C,RI,GE,=F'1') do i=n-1 to 1 by -1
LR R1,RI i
SLA R1,2 .
LA R2,A-4(R1) @a(i)
LA R3,A(R1) @a(i+1)
L R4,0(R2) r4=a(i)
L R5,0(R3) r5=a(i+1)
IF CR,R4,GT,R5 THEN if a(i)>a(i+1) then
MVI STABLE,X'00' stable=false
ST R5,0(R2) a(i)=r5
ST R4,0(R3) a(i+1)=r4
ENDIF , end if
BCTR RI,0 i=i-1
ENDDO , end do
ENDDO , until stable
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
NM1 DS F n-1
PG DC CL80' ' buffer
XDEC DS CL12 temp for xdeco
STABLE DS X stable
YREGS
RI EQU 6 i
END COCKTSRT</syntaxhighlight>
{{out}}
<pre>
-31 0 1 2 2 4 45 58 65 69 74 82 82 83 88 89 99 104 112 782
</pre>
=={{header|6502 Assembly}}==
Implemented in Easy6502. Output is provided below but it's best to watch this in action. Just copy and paste the code in, hit Assemble then Run. Make sure you check the Monitor box and set the address to 1200 and the length to 100. This takes about half as long as the bubble sort.
<syntaxhighlight lang="6502asm">define z_HL $00
define z_L $00
define z_H $01
define temp $02
define temp2 $03
 
define yINC $04
define yDEC $05
set_table:
dex
txa
sta $1200,y
iny
bne set_table ;stores $ff at $1200, $fe at $1201, etc.
lda #$12
sta z_H
lda #$00
sta z_L ;get the base address of the data table
 
lda #0
tax
tay ;clear regs
sty yINC ;yINC = 0
dey ;LDY #255
sty yDEC ;yDEC = 255
iny ;LDY #0
 
JSR COCKTAILSORT
BRK
COCKTAILSORT:
;yINC starts at the beginning and goes forward, yDEC starts at the end and goes back.
LDY yINC
LDA (z_HL),y ;get item Y
STA temp
INY
LDA (z_HL),y ;get item Y+1
DEY
STA temp2
CMP temp
bcs doNothing_Up ;if Y<=Y+1, do nothing. Otherwise swap them.
 
;we had to re-arrange an item.
lda temp
iny
sta (z_HL),y ;store the higher value at base+y+1
inx ;sort count. If zero at the end, we're done.
dey
lda temp2
sta (z_HL),y ;store the lower value at base+y
 
doNothing_Up:
LDY yDEC
LDA (z_HL),y
STA temp
DEY
LDA (z_HL),y
INY
STA temp2
CMP temp
bcc doNothing_Down ;if Y<=Y+1, do nothing. Otherwise swap them.
 
;we had to re-arrange an item.
lda temp
dey
sta (z_HL),y ;store the higher value at base+y+1
inx ;sort count. If zero at the end, we're done.
iny
lda temp2
sta (z_HL),y ;store the lower value at base+y
 
doNothing_Down:
INC yINC
DEC yDEC
LDA yINC
BPL COCKTAILSORT
 
CPX #0
BEQ doneSorting
LDX #0 ;reset the counter
LDY #0
STY yINC
DEY ;LDY #$FF
STY yDEC
INY ;LDY #0
JMP COCKTAILSORT
doneSorting:
RTS</syntaxhighlight>
 
{{out}}
<pre>
1200: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
1210: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
1220: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
1230: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
1240: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
1250: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
1260: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f
1270: 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f
1280: 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f
1290: 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f
12a0: a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af
12b0: b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf
12c0: c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf
12d0: d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df
12e0: e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef
12f0: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff
</pre>
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
<syntaxhighlight lang="aarch64 assembly">
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program cocktailSort64.s */
/*******************************************/
/* Constantes file */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeConstantesARM64.inc"
 
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessSortOk: .asciz "Table sorted.\n"
szMessSortNok: .asciz "Table not sorted !!!!!.\n"
sMessResult: .asciz "Value : @ \n"
szCarriageReturn: .asciz "\n"
.align 4
#TableNumber: .quad 1,3,6,2,5,9,10,8,4,7
TableNumber: .quad 10,9,8,7,6,-5,4,3,2,1
.equ NBELEMENTS, (. - TableNumber) / 8
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
sZoneConv: .skip 24
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: // entry of program
ldr x0,qAdrTableNumber // address number table
mov x1,0
mov x2,NBELEMENTS // number of élements
bl cocktailSort
ldr x0,qAdrTableNumber // address number table
bl displayTable
ldr x0,qAdrTableNumber // address number table
mov x1,NBELEMENTS // number of élements
bl isSorted // control sort
cmp x0,1 // sorted ?
beq 1f
ldr x0,qAdrszMessSortNok // no !! error sort
bl affichageMess
b 100f
1: // yes
ldr x0,qAdrszMessSortOk
bl affichageMess
100: // standard end of the program
mov x0,0 // return code
mov x8,EXIT // request to exit program
svc 0 // perform the system call
qAdrsZoneConv: .quad sZoneConv
qAdrszCarriageReturn: .quad szCarriageReturn
qAdrsMessResult: .quad sMessResult
qAdrTableNumber: .quad TableNumber
qAdrszMessSortOk: .quad szMessSortOk
qAdrszMessSortNok: .quad szMessSortNok
/******************************************************************/
/* control sorted table */
/******************************************************************/
/* x0 contains the address of table */
/* x1 contains the number of elements > 0 */
/* x0 return 0 if not sorted 1 if sorted */
isSorted:
stp x2,lr,[sp,-16]! // save registers
stp x3,x4,[sp,-16]! // save registers
mov x2,0
ldr x4,[x0,x2,lsl 3]
1:
add x2,x2,1
cmp x2,x1
bge 99f
ldr x3,[x0,x2, lsl 3]
cmp x3,x4
blt 98f
mov x4,x3
b 1b
98:
mov x0,0 // not sorted
b 100f
99:
mov x0,1 // sorted
100:
ldp x3,x4,[sp],16 // restaur 2 registers
ldp x2,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/******************************************************************/
/* cocktail sort */
/******************************************************************/
/* x0 contains the address of table */
/* x1 contains the first element */
/* x2 contains the number of element */
cocktailSort:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
stp x4,x5,[sp,-16]! // save registers
stp x6,x7,[sp,-16]! // save registers
stp x8,x9,[sp,-16]! // save registers
sub x2,x2,1 // compute i = n - 1
1: // start loop 1
mov x3,x1 // start index
mov x9,0
sub x7,x2,1
2: // start loop 2
add x4,x3,1
ldr x5,[x0,x3,lsl 3] // load value A[j]
ldr x6,[x0,x4,lsl 3] // load value A[j+1]
cmp x6,x5 // compare value
bge 3f
str x6,[x0,x3,lsl 3] // if smaller inversion
str x5,[x0,x4,lsl 3]
mov x9,1 // top table not sorted
3:
add x3,x3,1 // increment index j
cmp x3,x7 // end ?
ble 2b // no -> loop 2
cmp x9,0 // table sorted ?
beq 100f // yes -> end
mov x9,0
mov x3,x7
4:
add x4,x3,1
ldr x5,[x0,x3,lsl 3] // load value A[j]
ldr x6,[x0,x4,lsl 3] // load value A[j+1]
cmp x6,x5 // compare value
bge 5f
str x6,[x0,x3,lsl 3] // if smaller inversion
str x5,[x0,x4,lsl 3]
mov x9,1 // top table not sorted
5:
sub x3,x3,1 // decrement index j
cmp x3,x1 // end ?
bge 4b // no -> loop 2
 
cmp x9,0 // table sorted ?
bne 1b // no -> loop 1
100:
ldp x8,x9,[sp],16 // restaur 2 registers
ldp x6,x7,[sp],16 // restaur 2 registers
ldp x4,x5,[sp],16 // restaur 2 registers
ldp x2,x3,[sp],16 // restaur 2 registers
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/******************************************************************/
/* Display table elements */
/******************************************************************/
/* x0 contains the address of table */
displayTable:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
mov x2,x0 // table address
mov x3,0
1: // loop display table
ldr x0,[x2,x3,lsl 3]
ldr x1,qAdrsZoneConv
bl conversion10S // décimal conversion
ldr x0,qAdrsMessResult
ldr x1,qAdrsZoneConv
bl strInsertAtCharInc // insert result at @ character
bl affichageMess // display message
add x3,x3,1
cmp x3,NBELEMENTS - 1
ble 1b
ldr x0,qAdrszCarriageReturn
bl affichageMess
100:
ldp x2,x3,[sp],16 // restaur 2 registers
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/********************************************************/
/* File Include fonctions */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
 
</syntaxhighlight>
=={{header|Action!}}==
<syntaxhighlight lang="action!">PROC PrintArray(INT ARRAY a INT size)
INT i
 
Put('[)
FOR i=0 TO size-1
DO
IF i>0 THEN Put(' ) FI
PrintI(a(i))
OD
Put(']) PutE()
RETURN
 
PROC CoctailSort(INT ARRAY a INT size)
INT i,tmp
BYTE swapped
 
DO
swapped=0
i=0
WHILE i<size-1
DO
IF a(i)>a(i+1) THEN
tmp=a(i) a(i)=a(i+1) a(i+1)=tmp
swapped=1
FI
i==+1
OD
 
IF swapped=0 THEN EXIT FI
 
swapped=0
i=size-1
WHILE i>=0
DO
IF a(i)>a(i+1) THEN
tmp=a(i) a(i)=a(i+1) a(i+1)=tmp
swapped=1
FI
i==-1
OD
 
UNTIL swapped=0
OD
RETURN
 
PROC Test(INT ARRAY a INT size)
PrintE("Array before sort:")
PrintArray(a,size)
CoctailSort(a,size)
PrintE("Array after sort:")
PrintArray(a,size)
PutE()
RETURN
 
PROC Main()
INT ARRAY
a(10)=[1 4 65535 0 3 7 4 8 20 65530],
b(21)=[10 9 8 7 6 5 4 3 2 1 0
65535 65534 65533 65532 65531
65530 65529 65528 65527 65526],
c(8)=[101 102 103 104 105 106 107 108],
d(12)=[1 65535 1 65535 1 65535 1
65535 1 65535 1 65535]
Test(a,10)
Test(b,21)
Test(c,8)
Test(d,12)
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Cocktail_Sort.png Screenshot from Atari 8-bit computer]
<pre>
Array before sort:
[1 4 -1 0 3 7 4 8 20 -6]
Array after sort:
[-6 -1 0 1 3 4 4 7 8 20]
 
Array before sort:
[10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10]
Array after sort:
[-10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10]
 
Array before sort:
[101 102 103 104 105 106 107 108]
Array after sort:
[101 102 103 104 105 106 107 108]
 
Array before sort:
[1 -1 1 -1 1 -1 1 -1 1 -1 1 -1]
Array after sort:
[-1 -1 -1 -1 -1 -1 1 1 1 1 1 1]
</pre>
 
=={{header|ActionScript}}==
<langsyntaxhighlight ActionScriptlang="actionscript">function cocktailSort(input:Array):Array {
do {
var swapped:Boolean=false;
Line 47 ⟶ 552:
} while (swapped);
return input;
}</langsyntaxhighlight>
 
=={{header|Ada}}==
<langsyntaxhighlight Adalang="ada">with Ada.Text_Io; use Ada.Text_Io;
 
procedure Cocktail_Sort_Test is
Line 86 ⟶ 591:
Cocktail_Sort(Data);
Put_Line(Data);
end Cocktail_Sort_Test;</langsyntaxhighlight>
 
=={{header|ALGOL 60}}==
{{works with|A60}}
<syntaxhighlight lang="algol60">begin
comment Sorting algorithms/Cocktail sort - Algol 60;
integer nA;
nA:=20;
begin
integer array A[1:nA];
 
procedure cocktailsort(lb,ub);
value lb,ub; integer lb,ub;
begin
integer i,lbx,ubx;
boolean swapped;
lbx:=lb; ubx:=ub-1; swapped :=true;
for i:=1 while swapped do begin
procedure swap(i); value i; integer i;
begin
integer temp;
temp :=A[i];
A[i] :=A[i+1];
A[i+1]:=temp;
swapped:=true
end swap;
swapped:=false;
for i:=lbx step 1 until ubx do if A[i]>A[i+1] then swap(i);
if swapped
then begin
for i:=ubx step -1 until lbx do if A[i]>A[i+1] then swap(i);
ubx:=ubx-1; lbx:=lbx+1
end
end
end cocktailsort;
procedure inittable(lb,ub);
value lb,ub; integer lb,ub;
begin
integer i;
for i:=lb step 1 until ub do A[i]:=entier(rand*100)
end inittable;
procedure writetable(lb,ub);
value lb,ub; integer lb,ub;
begin
integer i;
for i:=lb step 1 until ub do outinteger(1,A[i]);
outstring(1,"\n")
end writetable;
nA:=20;
inittable(1,nA);
writetable(1,nA);
cocktailsort(1,nA);
writetable(1,nA)
end
end </syntaxhighlight>
{{out}}
<pre>
6 92 61 64 73 3 81 28 62 67 83 33 77 14 16 23 47 19 33 78
3 6 14 16 19 23 28 33 33 47 61 62 64 67 73 77 78 81 83 92
</pre>
 
=={{header|ALGOL 68}}==
<langsyntaxhighlight lang="algol68">MODE DATA = CHAR;
PROC swap = (REF DATA a,b)VOID:(
DATA tmp:=a; a:=b; b:=tmp
Line 120 ⟶ 691:
[32]CHAR data := "big fjords vex quick waltz nymph";
cocktail sort(data);
print(data)</langsyntaxhighlight>
{{out}}
Output:<pre>
<pre> abcdefghiijklmnopqrstuvwxyz</pre>
 
Alternatively - when the data records are large - the data can be manipulated
indirectly, thus removing the need to actually swap large chunks of memory
as only addresses are swapped.
<langsyntaxhighlight lang="algol68">MODE DATA = REF CHAR;
PROC swap = (REF DATA a,b)VOID:(
DATA tmp:=a; a:=b; b:=tmp
Line 138 ⟶ 708:
cocktail sort(ref data);
FOR i TO UPB ref data DO print(ref data[i]) OD; print(new line);
print((data))</langsyntaxhighlight>
{{out}}<pre> abcdefghiijklmnopqrstuvwxyz
Output:<pre>
abcdefghiijklmnopqrstuvwxyz
big fjords vex quick waltz nymph</pre>
The above two routines both scan the entire width of the array, in both directions, even though the first and last elements of each sweep had already reached their final destination during the previous pass. The solution is to zig-zag, but have the sweeps shorten and converge on the centre element. This reduces the number of comparisons required by about 50%.
 
<syntaxhighlight lang="algol68">PROC odd even sort = (REF []DATA a)VOID: (
The above two routines both scan the entire width of the array, in both
directions, even though the first and last elements of each sweep had already
reached their final destination during the previous pass. The solution is
to zig-zag, but have the sweeps shorten and converge on the centre element.
This reduces the number of comparisons required by about 50%.
<lang algol68>PROC odd even sort = (REF []DATA a)VOID: (
FOR offset FROM 0 DO
BOOL swapped := FALSE;
Line 170 ⟶ 734:
OD;
break do od loop: SKIP
);</langsyntaxhighlight>
 
=={{header|ALGOL W}}==
As noted in the ALGOL 68 sample above, the highest and lowest elements are sorted into their correct positions each time through the main loop.
This implementation optimises by reducing the number of elements to sort on each pass through the main loop.
<syntaxhighlight lang="algolw">begin
% As algol W does not allow overloading, we have to have type-specific %
% sorting procedures - this coctail sorts an integer array %
% as there is no way for the procedure to determine the array bounds, we %
% pass the lower and upper bounds in lb and ub %
procedure coctailSortIntegers( integer array item( * )
; integer value lb
; integer value ub
) ;
begin
integer lower, upper;
 
lower := lb;
upper := ub - 1;
 
while
begin
logical swapped;
 
procedure swap( integer value i ) ;
begin
integer val;
val := item( i );
item( i ) := item( i + 1 );
item( i + 1 ) := val;
swapped := true;
end swap ;
 
swapped := false;
for i := lower until upper do if item( i ) > item( i + 1 ) then swap( i );
if swapped
then begin
% there was at least one unordered element so try a 2nd sort pass %
for i := upper step -1 until lower do if item( i ) > item( i + 1 ) then swap( i );
upper := upper - 1; lower := lower + 1;
end if_swapped ;
swapped
end
do begin end;
end coctailSortIntegers ;
 
begin % test the sort %
integer array data( 1 :: 10 );
 
procedure writeData ;
begin
write( data( 1 ) );
for i := 2 until 10 do writeon( data( i ) );
end writeData ;
 
% initialise data to unsorted values %
integer dPos;
dPos := 1;
for i := 16, 2, -6, 9, 90, 14, 0, 23, 8, 9
do begin
data( dPos ) := i;
dPos := dPos + 1;
end for_i ;
 
i_w := 3; s_w := 1; % set output format %
writeData;
coctailSortIntegers( data, 1, 10 );
writeData;
end test ;
end.</syntaxhighlight>
{{out}}
<pre>
16 2 -6 9 90 14 0 23 8 9
-6 0 2 8 9 9 14 16 23 90
</pre>
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
/* ARM assembly Raspberry PI */
/* program cocktailSort.s */
/* REMARK 1 : this program use routines in a include file
see task Include a file language arm assembly
for the routine affichageMess conversion10
see at end of this program the instruction include */
/* for constantes see task include a file in arm assembly */
/************************************/
/* Constantes */
/************************************/
.include "../constantes.inc"
 
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessSortOk: .asciz "Table sorted.\n"
szMessSortNok: .asciz "Table not sorted !!!!!.\n"
sMessResult: .asciz "Value : @ \n"
szCarriageReturn: .asciz "\n"
.align 4
#TableNumber: .int 1,3,6,2,5,9,10,8,4,7
TableNumber: .int 10,9,8,7,6,5,4,3,2,1
.equ NBELEMENTS, (. - TableNumber) / 4
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
sZoneConv: .skip 24
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: @ entry of program
1:
ldr r0,iAdrTableNumber @ address number table
mov r1,#0
mov r2,#NBELEMENTS @ number of élements
bl cocktailSort
ldr r0,iAdrTableNumber @ address number table
bl displayTable
ldr r0,iAdrTableNumber @ address number table
mov r1,#NBELEMENTS @ number of élements
bl isSorted @ control sort
cmp r0,#1 @ sorted ?
beq 2f
ldr r0,iAdrszMessSortNok @ no !! error sort
bl affichageMess
b 100f
2: @ yes
ldr r0,iAdrszMessSortOk
bl affichageMess
100: @ standard end of the program
mov r0, #0 @ return code
mov r7, #EXIT @ request to exit program
svc #0 @ perform the system call
iAdrszCarriageReturn: .int szCarriageReturn
iAdrsMessResult: .int sMessResult
iAdrTableNumber: .int TableNumber
iAdrszMessSortOk: .int szMessSortOk
iAdrszMessSortNok: .int szMessSortNok
/******************************************************************/
/* control sorted table */
/******************************************************************/
/* r0 contains the address of table */
/* r1 contains the number of elements > 0 */
/* r0 return 0 if not sorted 1 if sorted */
isSorted:
push {r2-r4,lr} @ save registers
mov r2,#0
ldr r4,[r0,r2,lsl #2]
1:
add r2,#1
cmp r2,r1
movge r0,#1
bge 100f
ldr r3,[r0,r2, lsl #2]
cmp r3,r4
movlt r0,#0
blt 100f
mov r4,r3
b 1b
100:
pop {r2-r4,lr}
bx lr @ return
/******************************************************************/
/* cocktail Sort */
/******************************************************************/
/* r0 contains the address of table */
/* r1 contains the first element */
/* r2 contains the number of element */
cocktailSort:
push {r1-r9,lr} @ save registers
sub r2,r2,#1 @ compute i = n - 1
add r8,r1,#1
1: @ start loop 1
mov r3,r1 @ start index
mov r9,#0
sub r7,r2,#1 @ max
2: @ start loop 2
add r4,r3,#1
ldr r5,[r0,r3,lsl #2] @ load value A[j]
ldr r6,[r0,r4,lsl #2] @ load value A[j+1]
cmp r6,r5 @ compare value
strlt r6,[r0,r3,lsl #2] @ if smaller inversion
strlt r5,[r0,r4,lsl #2]
movlt r9,#1 @ top table not sorted
add r3,#1 @ increment index j
cmp r3,r7 @ end ?
ble 2b @ no -> loop 2
cmp r9,#0 @ table sorted ?
beq 100f @ yes -> end
@ bl displayTable
mov r9,#0
mov r3,r7
3:
add r4,r3,#1
ldr r5,[r0,r3,lsl #2] @ load value A[j]
ldr r6,[r0,r4,lsl #2] @ load value A[j+1]
cmp r6,r5 @ compare value
strlt r6,[r0,r3,lsl #2] @ if smaller inversion
strlt r5,[r0,r4,lsl #2]
movlt r9,#1 @ top table not sorted
sub r3,#1 @ decrement index j
cmp r3,r1 @ end ?
bge 3b @ no -> loop 2
@ bl displayTable
cmp r9,#0 @ table sorted ?
bne 1b @ no -> loop 1
100:
pop {r1-r9,lr}
bx lr @ return
/******************************************************************/
/* Display table elements */
/******************************************************************/
/* r0 contains the address of table */
displayTable:
push {r0-r3,lr} @ save registers
mov r2,r0 @ table address
mov r3,#0
1: @ loop display table
ldr r0,[r2,r3,lsl #2]
ldr r1,iAdrsZoneConv @
bl conversion10S @ décimal conversion signed
ldr r0,iAdrsMessResult
ldr r1,iAdrsZoneConv @ insert conversion
bl strInsertAtCharInc
bl affichageMess @ display message
add r3,#1
cmp r3,#NBELEMENTS - 1
ble 1b
ldr r0,iAdrszCarriageReturn
bl affichageMess
100:
pop {r0-r3,lr}
bx lr
iAdrsZoneConv: .int sZoneConv
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
.include "../affichage.inc"
 
</syntaxhighlight>
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">trySwap: function [arr,i][
if arr\[i] < arr\[i-1] [
tmp: arr\[i]
arr\[i]: arr\[i-1]
arr\[i-1]: tmp
return null
]
return true
]
cocktailSort: function [items][
t: false
l: size items
while [not? t][
t: true
loop 1..dec l 'i [
if null? trySwap items i ->
t: false
]
if t -> break
loop (l-1)..1 'i [
if null? trySwap items i ->
t: false
]
]
return items
]
 
print cocktailSort [3 1 2 8 5 7 9 4 6]</syntaxhighlight>
 
{{out}}
 
<pre>1 2 3 4 5 6 7 8 9</pre>
 
=={{header|AutoHotkey}}==
contributed by Laszlo on the ahk [http://www.autohotkey.com/forum/post-276379.html#276379 forum]
<langsyntaxhighlight AutoHotkeylang="autohotkey">MsgBox % CocktailSort("")
MsgBox % CocktailSort("xxx")
MsgBox % CocktailSort("3,2,1")
Line 204 ⟶ 1,052:
sorted .= "," . array%A_Index%
Return SubStr(sorted,2) ; drop leading comma
}</syntaxhighlight>
}</lang>
 
=={{header|AWK}}==
Sort the standard input and print it to standard output
<langsyntaxhighlight lang="awk">{
line[NR] = $0
}
Line 237 ⟶ 1,085:
print line[i]
}
}</langsyntaxhighlight>
 
=={{header|BBC BASIC}}==
Sorting an integer array. '%' indicates integer variable in BBC BASIC
<langsyntaxhighlight BBClang="bbc BASICbasic">DEF PROC_ShakerSort(Size%)
 
Start%=2
Line 259 ⟶ 1,107:
UNTIL ( ( End% * Direction% ) < ( Start% * Direction% ) )
 
ENDPROC</langsyntaxhighlight>
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
 
// can be any swap function. This swap is optimized for numbers.
#define try_swap { if (a[i] < a[i - 1])\
void swap(int *x, int *y) {
{ t = a[i]; a[i] = a[i - 1]; a[i - 1] = t; t = 0;} }
if(x == y)
 
return;
void cocktailsort(int *a, size_t len)
*x ^= *y;
{
size_t*y i^= *x;
int t*x ^= 0*y;
}
while (!t) {
void cocktailsort(int *a, size_t n) {
for (i = 1, t = 1; i < len; i++) try_swap;
while(1) {
if (t) break;
// packing two similar loops into one
for (i = len - 1, t = 1; i; i--) try_swap;
char flag;
size_t start[2] = {1, n - 1},
end[2] = {n, 0},
inc[2] = {1, -1};
for(int it = 0; it < 2; ++it) {
flag = 1;
for(int i = start[it]; i != end[it]; i += inc[it])
if(a[i - 1] > a[i]) {
swap(a + i - 1, a + i);
flag = 0;
}
if(flag)
return;
}
}
}
 
int main(void) {
int a[] = { 5, -1, 101, -4, 0, 1, 8, 6, 2, 3 };
{
size_t n = sizeof(a)/sizeof(a[0]);
int x[] = { 5, -1, 101, -4, 0, 1, 8, 6, 2, 3 };
size_t i, len = sizeof(x)/sizeof(x[0]);
 
cocktailsort(xa, lenn);
for (size_t i = 0; i < lenn; i++i)
printf("%d\n ", xa[i]);
return 0;
}</langsyntaxhighlight>
 
'''Output''':
 
<syntaxhighlight lang="text">-4 -1 0 1 2 3 5 6 8 101</syntaxhighlight>
 
===Generic version===
This version can be used with arrays of any type, like the standard library function qsort.
<syntaxhighlight lang="c">#include <stdbool.h>
#include <stdio.h>
#include <string.h>
 
void swap(char* p1, char* p2, size_t size) {
for (; size-- > 0; ++p1, ++p2) {
char tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
}
 
void cocktail_sort(void* base, size_t count, size_t size,
int (*cmp)(const void*, const void*)) {
char* begin = base;
char* end = base + size * count;
if (end == begin)
return;
bool swapped = true;
for (end -= size; swapped; ) {
swapped = false;
for (char* p = begin; p < end; p += size) {
char* q = p + size;
if (cmp(p, q) > 0) {
swap(p, q, size);
swapped = true;
}
}
if (!swapped)
break;
swapped = false;
for (char* p = end; p > begin; p -= size) {
char* q = p - size;
if (cmp(q, p) > 0) {
swap(p, q, size);
swapped = true;
}
}
}
}
 
int string_compare(const void* p1, const void* p2) {
const char* const* s1 = p1;
const char* const* s2 = p2;
return strcmp(*s1, *s2);
}
 
void print(const char** a, size_t len) {
for (size_t i = 0; i < len; ++i)
printf("%s ", a[i]);
printf("\n");
}
 
int main() {
const char* a[] = { "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine", "ten" };
const size_t len = sizeof(a)/sizeof(a[0]);
printf("before: ");
print(a, len);
cocktail_sort(a, len, sizeof(char*), string_compare);
printf("after: ");
print(a, len);
return 0;
}</syntaxhighlight>
 
{{out}}
<pre>
before: one two three four five six seven eight nine ten
after: eight five four nine one seven six ten three two
</pre>
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight lang="csharp">public static void cocktailSort(int[] A)
{
bool swapped;
Line 325 ⟶ 1,263:
//if no elements have been swapped, then the list is sorted
} while (swapped);
}</langsyntaxhighlight>
 
=={{header|COBOLC++}}==
<syntaxhighlight lang="cpp">
#include <iostream>
#include <windows.h>
 
const int EL_COUNT = 77, LLEN = 11;
This is procedure division only.
 
class cocktailSort
<lang cobol> C-SORT SECTION.
{
public:
void sort( int* arr, int len )
{
bool notSorted = true;
while( notSorted )
{
notSorted = false;
for( int a = 0; a < len - 1; a++ )
{
if( arr[a] > arr[a + 1] )
{
sSwap( arr[a], arr[a + 1] );
notSorted = true;
}
}
if( !notSorted ) break;
notSorted = false;
for( int a = len - 1; a > 0; a-- )
{
if( arr[a - 1] > arr[a] )
{
sSwap( arr[a], arr[a - 1] );
notSorted = true;
}
}
}
}
private:
void sSwap( int& a, int& b )
{
int t = a;
a = b; b = t;
}
};
 
int main( int argc, char* argv[] )
{
srand( GetTickCount() );
cocktailSort cs;
int arr[EL_COUNT];
for( int x = 0; x < EL_COUNT; x++ )
arr[x] = rand() % EL_COUNT + 1;
std::cout << "Original: " << std::endl << "==========" << std::endl;
for( int x = 0; x < EL_COUNT; x += LLEN )
{
for( int s = x; s < x + LLEN; s++ )
std::cout << arr[s] << ", ";
std::cout << std::endl;
}
//DWORD now = GetTickCount();
cs.sort( arr, EL_COUNT );
//now = GetTickCount() - now;
std::cout << std::endl << std::endl << "Sorted: " << std::endl << "========" << std::endl;
for( int x = 0; x < EL_COUNT; x += LLEN )
{
for( int s = x; s < x + LLEN; s++ )
std::cout << arr[s] << ", ";
std::cout << std::endl;
}
std::cout << std::endl << std::endl << std::endl << std::endl;
//std::cout << now << std::endl << std::endl;
return 0;
}
</syntaxhighlight>
 
=== Alternate version ===
Uses C++11. Compile with
g++ -std=c++11 cocktail.cpp
<syntaxhighlight lang="cpp">#include <algorithm>
#include <iostream>
#include <iterator>
 
template <typename RandomAccessIterator>
void cocktail_sort(RandomAccessIterator begin, RandomAccessIterator end) {
bool swapped = true;
while (begin != end-- && swapped) {
swapped = false;
for (auto i = begin; i != end; ++i) {
if (*(i + 1) < *i) {
std::iter_swap(i, i + 1);
swapped = true;
}
}
if (!swapped) {
break;
}
swapped = false;
for (auto i = end - 1; i != begin; --i) {
if (*i < *(i - 1)) {
std::iter_swap(i, i - 1);
swapped = true;
}
}
++begin;
}
}
 
int main() {
int a[] = {100, 2, 56, 200, -52, 3, 99, 33, 177, -199};
cocktail_sort(std::begin(a), std::end(a));
copy(std::begin(a), std::end(a), std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n";
}</syntaxhighlight>
{{out}}
<pre>
-199 -52 2 3 33 56 99 100 177 200
</pre>
 
=={{header|COBOL}}==
This is procedure division only.
<syntaxhighlight lang="cobol"> C-SORT SECTION.
C-000.
DISPLAY "SORT STARTING".
Line 368 ⟶ 1,431:
 
F-999.
EXIT.</langsyntaxhighlight>
 
=={{header|Common Lisp}}==
 
This version works on lists and vectors alike. The vector implementation is coded directly. The list version uses an intermediate vector.
<syntaxhighlight lang="lisp">(defun cocktail-sort-vector (vector predicate &aux (len (length vector)))
 
<lang lisp>(defun cocktail-sort-vector (vector predicate &aux (len (length vector)))
(labels ((scan (start step &aux swapped)
(loop for i = start then (+ i step) while (< 0 i len) do
Line 392 ⟶ 1,453:
(list (map-into sequence 'identity
(cocktail-sort-vector (coerce sequence 'vector)
predicate)))))</langsyntaxhighlight>
 
=={{header|D}}==
<syntaxhighlight lang="d">// Written in the D programming language.
<lang d>import std.stdio, std.algorithm;
module rosettaCode.sortingAlgorithms.cocktailSort;
 
import std.range;
void cocktailSort(Range)(Range data) {
bool swapped = false;
Range cocktailSort(Range)(Range data)
do {
if (isRandomAccessRange!Range && hasLvalueElements!Range) {
import std.algorithm : swap;
bool swapped = void;
void trySwap(E)(ref E lhs, ref E rhs) {
if (lhs > rhs) {
swap(lhs, rhs);
swapped = true;
}
}
 
if (data.length > 0) do {
swapped = false;
foreach (i; 0 .. data.length - 1)
if trySwap(data[i] >, data[i + 1]) {;
swap(data[i], data[i + 1]);
swapped = true;
}
if (!swapped)
break;
swapped = false;
foreach_reverse (i; 0 .. data.length - 1)
if trySwap(data[i] >, data[i + 1]) {;
swap(data[i], data[i + 1]);
swapped = true;
}
} while(swapped);
return data;
}
 
unittest {
assert (cocktailSort([3, 1, 5, 2, 4]) == [1, 2, 3, 4, 5]);
assert (cocktailSort([1, 2, 3, 4, 5]) == [1, 2, 3, 4, 5]);
assert (cocktailSort([5, 4, 3, 2, 1]) == [1, 2, 3, 4, 5]);
assert (cocktailSort((int[]).init) == []);
assert (cocktailSort(["John", "Kate", "Zerg", "Alice", "Joe", "Jane"]) ==
["Alice", "Jane", "Joe", "John", "Kate", "Zerg"]);
}
</syntaxhighlight>
 
{{out}}
<syntaxhighlight lang="d">
import rosettaCode.sortingAlgorithms.cocktailSort;
 
void main() {
import std.stdio, std.algorithm, std.range, std.random;
auto array = ["John", "Kate", "Zerg", "Alice", "Joe", "Jane"];
//generate 10 sorted random numbers in [0 .. 10)
cocktailSort(array);
rndGen.take(10).map!(a=>a%10).array.cocktailSort.writeln();
writeln(array);
}</langsyntaxhighlight>
<pre>[2, 2, 3, 4, 5, 5, 7, 7, 7, 8]</pre>
Output:
<pre>[Alice, Jane, Joe, John, Kate, Zerg]</pre>
 
=={{header|Delphi}}==
Line 428 ⟶ 1,510:
 
Static array is an arbitrary-based array of fixed length
<langsyntaxhighlight Delphilang="delphi">program TestShakerSort;
 
{$APPTYPE CONSOLE}
Line 491 ⟶ 1,573:
Writeln;
Readln;
end.</langsyntaxhighlight>
{{out}}
Output:
<pre>
0 3 86 20 27 67 31 16 37 42 8 47 7 84 5 29
Line 499 ⟶ 1,581:
 
=={{header|E}}==
<syntaxhighlight lang="e">/** Cocktail sort (in-place) */
 
<lang e>/** Cocktail sort (in-place) */
def cocktailSort(array) {
def swapIndexes := 0..(array.size() - 2)
Line 516 ⟶ 1,597:
}
}
}</langsyntaxhighlight>
 
Note that this solution contains no repeated code to handle the forward and reverse passes.
 
=={{header|Eiffel}}==
<syntaxhighlight lang="eiffel">
 
class
COCKTAIL_SORT [G -> COMPARABLE]
 
feature
 
cocktail_sort (ar: ARRAY [G]): ARRAY [G]
-- Array sorted in ascending order.
require
ar_not_empty: ar.count >= 1
local
not_swapped: BOOLEAN
sol: ARRAY [G]
i, j: INTEGER
t: G
do
create Result.make_empty
Result.deep_copy (ar)
from
until
not_swapped = True
loop
not_swapped := True
from
i := Result.lower
until
i = Result.upper - 1
loop
if Result [i] > Result [i + 1] then
Result := swap (Result, i)
not_swapped := False
end
i := i + 1
end
from
j := Result.upper - 1
until
j = Result.lower
loop
if Result [j] > Result [j + 1] then
Result := swap (Result, j)
not_swapped := False
end
j := j - 1
end
end
ensure
ar_is_sorted: is_sorted (Result)
end
 
feature{NONE}
 
swap (ar: ARRAY [G]; i: INTEGER): ARRAY [G]
-- Array with elements i and i+1 swapped.
require
ar_not_void: ar /= Void
i_is_in_bounds: ar.valid_index (i)
local
t: G
do
create Result.make_empty
Result.deep_copy (ar)
t := Result [i]
Result [i] := Result [i + 1]
Result [i + 1] := t
ensure
swapped_right: Result [i + 1] = ar [i]
swapped_left: Result [i] = ar [i + 1]
end
 
is_sorted (ar: ARRAY [G]): BOOLEAN
--- Is 'ar' sorted in ascending order?
require
ar_not_empty: ar.is_empty = False
local
i: INTEGER
do
Result := True
from
i := ar.lower
until
i = ar.upper
loop
if ar [i] > ar [i + 1] then
Result := False
end
i := i + 1
end
end
 
end
 
</syntaxhighlight>
Test:
<syntaxhighlight lang="eiffel">
 
class
APPLICATION
 
create
make
 
feature
 
make
do
test := <<5, 1, 99, 3, 2>>
io.put_string ("unsorted%N")
across
test as t
loop
io.put_string (t.item.out + "%T")
end
io.new_line
io.put_string ("sorted%N")
create cs
test := cs.cocktail_sort (test)
across
test as ar
loop
io.put_string (ar.item.out + "%T")
end
end
 
cs: COCKTAIL_SORT [INTEGER]
 
test: ARRAY [INTEGER]
 
end
 
</syntaxhighlight>
{{out}}
<pre>
unsorted
5 1 99 3 2
sorted
1 2 3 5 99
</pre>
 
=={{header|Elena}}==
ELENA 6.x :
<syntaxhighlight lang="elena">import extensions;
import system'math;
import system'routines;
extension op
{
cocktailSort()
{
var list := self.clone();
bool swapped := true;
while(swapped)
{
swapped := false;
for(int i := 0; i <= list.Length - 2; i += 1)
{
if (list[i]>list[i+1])
{
list.exchange(i,i+1);
swapped := true
}
};
ifnot (swapped)
{
^ list
};
swapped := false;
for(int i := list.Length - 2; i >= 0; i -= 1)
{
if (list[i]>list[i+1])
{
list.exchange(i,i+1);
swapped := true
}
}
};
^ list
}
}
public program()
{
var list := new int[]{3, 5, 1, 9, 7, 6, 8, 2, 4 };
console.printLine("before:", list.asEnumerable());
console.printLine("after :", list.cocktailSort().asEnumerable())
}</syntaxhighlight>
{{out}}
<pre>
before:3,5,1,9,7,6,8,2,4
after :1,2,3,4,5,6,7,8,9
</pre>
 
=={{header|Elixir}}==
<syntaxhighlight lang="elixir">defmodule Sort do
def cocktail_sort(list) when is_list(list), do: cocktail_sort(list, [], [])
defp cocktail_sort([], minlist, maxlist), do: Enum.reverse(minlist, maxlist)
defp cocktail_sort([x], minlist, maxlist), do: Enum.reverse(minlist, [x | maxlist])
defp cocktail_sort(list, minlist, maxlist) do
{max, rev} = cocktail_max(list, [])
{min, rest} = cocktail_min(rev, [])
cocktail_sort(rest, [min | minlist], [max | maxlist])
end
defp cocktail_max([max], list), do: {max, list}
defp cocktail_max([x,y | t], list) when x<y, do: cocktail_max([y | t], [x | list])
defp cocktail_max([x,y | t], list) , do: cocktail_max([x | t], [y | list])
defp cocktail_min([min], list), do: {min, list}
defp cocktail_min([x,y | t], list) when x>y, do: cocktail_min([y | t], [x | list])
defp cocktail_min([x,y | t], list) , do: cocktail_min([x | t], [y | list])
end
 
IO.inspect Sort.cocktail_sort([5,3,9,4,1,6,8,2,7])</syntaxhighlight>
 
{{out}}
<pre>
[1, 2, 3, 4, 5, 6, 7, 8, 9]
</pre>
 
=={{header|Euphoria}}==
<langsyntaxhighlight lang="euphoria">function cocktail_sort(sequence s)
integer swapped, d
object temp
Line 545 ⟶ 1,852:
constant s = rand(repeat(1000,10))
? s
? cocktail_sort(s)</langsyntaxhighlight>
{{out}}
 
Output:
<pre>{963,398,374,455,53,210,611,285,984,308}
{53,210,285,308,374,398,455,611,963,984}
</pre>
 
=={{header|Factor}}==
===Pseudocode translation===
This is a faithful translation of the pseudocode given in the task description. It uses lexical variables.
<syntaxhighlight lang="factor">USING: kernel locals math math.ranges sequences ;
 
:: cocktail-sort! ( seq -- seq' )
f :> swapped! ! bind false to mutable lexical variable 'swapped'. This must be done outside both while quotations so it is in scope of both.
[ swapped ] [ ! is swapped true? Then execute body quotation. 'do' executes body quotation before predicate on first pass.
f swapped! ! set swapped to false
seq length 2 - [| i | ! for each i in 0 to seq length - 2 do
i i 1 + [ seq nth ] bi@ > ! is element at index i greater than element at index i + 1?
[ i i 1 + seq exchange t swapped! ] when ! if so, swap them and set swapped to true
] each-integer
swapped [ ! skip to end of loop if swapped is false
seq length 2 - 0 [a,b] [| i | ! for each i in seq length - 2 to 0 do
i i 1 + [ seq nth ] bi@ > ! is element at index i greater than element at index i + 1?
[ i i 1 + seq exchange t swapped! ] when ! if so, swap them and set swapped to true
] each
] when
] do while
seq ; ! return the sequence</syntaxhighlight>
 
===More idiomatic===
This is perhaps a more idiomatic solution, eschewing the use of lexical variables. If we had tried to translate the pseudocode directly, we'd be dealing with a data stack that is 6+ values deep. Our main strategy against this is to factor the problem into short words that deal with only a few items at a time. When writing mutating words, we can simplify matters by writing words that return nothing, and letting the caller decide if and how to leave references on the data stack.
<syntaxhighlight lang="factor">USING: fry kernel math math.ranges namespaces sequences ;
 
SYMBOL: swapped?
 
: dupd+ ( m obj -- m n obj ) [ dup 1 + ] dip ;
 
: 2nth ( n seq -- elt1 elt2 ) dupd+ [ nth ] curry bi@ ;
 
: ?exchange ( n seq -- )
2dup 2nth > [ dupd+ exchange swapped? on ] [ 2drop ] if ;
 
: cocktail-pass ( seq forward? -- )
'[ length 2 - 0 _ [ swap ] when [a,b] ] [ ] bi
[ ?exchange ] curry each ;
 
: (cocktail-sort!) ( seq -- seq' )
swapped? off dup t cocktail-pass
swapped? get [ dup f cocktail-pass ] when ;
 
: cocktail-sort! ( seq -- seq' )
[ swapped? get ] [ (cocktail-sort!) ] do while ;</syntaxhighlight>
 
=={{header|Forth}}==
<syntaxhighlight lang="forth">defer precedes ( addr addr -- flag )
\ e.g. ' < is precedes
: sort ( a n --)
1- cells bounds 2>r false
begin
0= dup
while
2r@ ?do
i cell+ @ i @ over over precedes ( mark unsorted )
if i cell+ ! i ! dup xor else drop drop then
1 cells +loop
0= dup
while
2r@ swap 1 cells - ?do
i cell+ @ i @ over over precedes ( mark unsorted )
if i cell+ ! i ! dup xor else drop drop then
-1 cells +loop
repeat then drop 2r> 2drop
;</syntaxhighlight>
This is an optimized version:
<syntaxhighlight lang="forth">: sort
1- cells bounds 1
begin
>r over over r@ -rot true -rot
r> 0< if 1 cells - then
?do
i cell+ @ i @ over over precedes ( mark unsorted )
if i cell+ ! i ! dup xor else drop drop then
over cells +loop
>r negate >r swap r@ cells + r> r>
until drop drop drop
;</syntaxhighlight>
 
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<langsyntaxhighlight lang="fortran">PROGRAM COCKTAIL
IMPLICIT NONE
 
Line 597 ⟶ 1,983:
END SUBROUTINE Cocktail_sort
 
END PROGRAM COCKTAIL</langsyntaxhighlight>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">' version 21-10-2016
' compile with: fbc -s console
' for boundry checks on array's compile with: fbc -s console -exx
 
Sub cocktailsort(bs() As Long)
' sort from lower bound to the highter bound
' array's can have subscript range from -2147483648 to +2147483647
Dim As Long lb = LBound(bs)
Dim As Long ub = UBound(bs) -1
Dim As Long done, i
 
Do
done = 0 ' going up
For i = lb To ub
If bs(i) > bs(i +1) Then
Swap bs(i), bs(i +1)
done = 1
End If
Next
ub = ub -1
If done = 0 Then Exit Do ' 0 means the array is sorted
done = 0 ' going down
For i = ub To lb Step -1
If bs(i) > bs(i +1) Then
Swap bs(i), bs(i +1)
done = 1
End If
Next
lb = lb +1
Loop Until done = 0 ' 0 means the array is sorted
 
End Sub
 
' ------=< MAIN >=------
 
Dim As Long i, array(-7 To 7)
 
Dim As Long a = LBound(array), b = UBound(array)
 
Randomize Timer
For i = a To b : array(i) = i : Next
For i = a To b ' little shuffle
Swap array(i), array(Int(Rnd * (b - a +1)) + a)
Next
 
 
Print "unsorted ";
For i = a To b : Print Using "####"; array(i); : Next : Print
cocktailsort(array()) ' sort the array
Print " sorted ";
For i = a To b : Print Using "####"; array(i); : Next : Print
 
 
' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End</syntaxhighlight>
{{out}}
<pre>unsorted -2 -4 7 -5 -7 4 2 -1 5 -6 6 1 0 -3 3
sorted -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7</pre>
 
=={{header|Gambas}}==
'''[https://gambas-playground.proko.eu/?gist=ee5467e58f0ef649373eed5a2503b988 Click this link to run this code]'''
<syntaxhighlight lang="gambas">Public Sub Main()
Dim siCount, siRev, siProcess As Short
Dim bSorting As Boolean
Dim byToSort As Byte[] = [249, 28, 111, 36, 171, 98, 29, 448, 44, 154, 147, 102, 46, 183, 24,
120, 19, 123, 2, 17, 226, 11, 211, 25, 191, 205, 77]
 
Print "To sort: -"
ShowWorking(byToSort)
Print
Repeat
bSorting = False
siRev = byToSort.Max - 1
For siCount = 0 To byToSort.Max - 1
siProcess = siCount
GoSub Check
siProcess = siRev
GoSub Check
Dec siRev
Next
If bSorting Then ShowWorking(byToSort)
Until bSorting = False
 
Return
 
Check:
 
If byToSort[siProcess] > byToSort[siProcess + 1] Then
Swap byToSort[siProcess], byToSort[siProcess + 1]
bSorting = True
Endif
 
Return
 
End
'-----------------------------------------
Public Sub ShowWorking(byToSort As Byte[])
Dim siCount As Byte
For siCount = 0 To byToSort.Max
Print Str(byToSort[siCount]);
If siCount <> byToSort.Max Then Print ",";
Next
Print
End</syntaxhighlight>
Output:
<pre>
To sort: -
249,28,111,36,171,98,29,192,44,154,147,102,46,183,24,120,19,123,2,17,226,11,211,25,191,205,77
 
2,28,111,36,171,98,29,192,44,154,147,102,46,183,24,120,19,123,11,17,226,25,211,77,191,205,249
2,11,28,36,111,98,29,171,44,154,147,102,46,183,24,120,19,123,17,25,192,77,211,191,205,226,249
2,11,17,28,36,98,29,111,44,154,147,102,46,171,24,120,19,123,25,77,183,191,192,205,211,226,249
2,11,17,19,28,36,29,98,44,111,147,102,46,154,24,120,25,123,77,171,183,191,192,205,211,226,249
2,11,17,19,24,28,29,36,44,98,111,102,46,147,25,120,77,123,154,171,183,191,192,205,211,226,249
2,11,17,19,24,25,28,29,36,44,98,102,46,111,77,120,123,147,154,171,183,191,192,205,211,226,249
2,11,17,19,24,25,28,29,36,44,46,98,77,102,111,120,123,147,154,171,183,191,192,205,211,226,249
2,11,17,19,24,25,28,29,36,44,46,77,98,102,111,120,123,147,154,171,183,191,192,205,211,226,249
</pre>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 635 ⟶ 2,148:
}
}
}</langsyntaxhighlight>
 
More generic version that sorts anything that implements <code>sort.Interface</code>:
<langsyntaxhighlight lang="go">package main
 
import (
Line 676 ⟶ 2,188:
}
}
}</langsyntaxhighlight>
 
=={{header|Groovy}}==
Solution:
<langsyntaxhighlight lang="groovy">def makeSwap = { a, i, j = i+1 -> print "."; a[[j,i]] = a[[i,j]] }
def checkSwap = { a, i, j = i+1 -> [(a[i] > a[j])].find{ it }.each { makeSwap(a, i, j) } }
Line 693 ⟶ 2,205:
}
list
}</langsyntaxhighlight>
 
Test:
<langsyntaxhighlight lang="groovy">println cocktailSort([23,76,99,58,97,57,35,89,51,38,95,92,24,46,31,24,14,12,57,78,4])
println cocktailSort([88,18,31,44,4,0,8,81,14,78,20,76,84,33,73,75,82,5,62,70,12,7,1])
 
println cocktailSort([ 3, 14, 1, 5, 9, 2, 6, 3 ])
println cocktailSort([ 3, 14 ])
println cocktailSort([ 33, 14 ])</langsyntaxhighlight>
{{out}}
 
Output:
<pre>..............................................................................................................................................[4, 12, 14, 23, 24, 24, 31, 35, 38, 46, 51, 57, 57, 58, 76, 78, 89, 92, 95, 97, 99]
.........................................................................................................................................[0, 1, 4, 5, 7, 8, 12, 14, 18, 20, 31, 33, 44, 62, 70, 73, 75, 76, 78, 81, 82, 84, 88]
Line 711 ⟶ 2,221:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">cocktailSort :: Ord a => [a] -> [a]
cocktailSort l
| not swapped1 = l
Line 724 ⟶ 2,234:
| otherwise = swappingPass op (swapped, x1 : l) (x2 : xs)
swappingPass _ (swapped, l) [x] = (swapped, x : l)
swappingPass _ pair [] = pair</langsyntaxhighlight>
 
=={{header|Ksh}}==
<syntaxhighlight lang="ksh">#!/bin/ksh
 
# cocktail shaker sort
 
# # Variables:
#
integer TRUE=1
integer FALSE=0
typeset -a arr=( 5 -1 101 -4 0 1 8 6 2 3 )
 
# # Functions:
#
function _swap {
typeset _i ; integer _i=$1
typeset _j ; integer _j=$2
typeset _array ; nameref _array="$3"
typeset _swapped ; nameref _swapped=$4
 
typeset _tmp ; _tmp=${_array[_i]}
_array[_i]=${_array[_j]}
_array[_j]=${_tmp}
_swapped=$TRUE
}
 
######
# main #
######
 
print "( ${arr[*]} )"
 
integer i j
integer swapped=$TRUE
while (( swapped )); do
swapped=$FALSE
for (( i=0 ; i<${#arr[*]}-2 ; i++ , j=i+1 )); do
(( arr[i] > arr[j] )) && _swap ${i} ${j} arr swapped
done
(( ! swapped )) && break
 
swapped=$FALSE
for (( i=${#arr[*]}-2 ; i>0 ; i-- , j=i+1 )); do
(( arr[i] > arr[j] )) && _swap ${i} ${j} arr swapped
done
done
 
print "( ${arr[*]} )"</syntaxhighlight>
{{out}}
<pre>( 5 -1 101 -4 0 1 8 6 2 3 )
( -4 -1 0 1 2 3 5 6 8 101 )</pre>
 
 
=={{header|Haxe}}==
<syntaxhighlight lang="haxe">class CocktailSort {
@:generic
public static function sort<T>(arr:Array<T>) {
var swapped = false;
do {
swapped = false;
for (i in 0...(arr.length - 1)) {
if (Reflect.compare(arr[i], arr[i + 1]) > 0) {
var temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
swapped = true;
}
}
if (!swapped) break;
swapped = false;
var i = arr.length - 2;
while (i >= 0) {
if (Reflect.compare(arr[i], arr[i + 1]) > 0) {
var temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
swapped = true;
}
i--;
}
} while (swapped);
}
}
 
class Main {
static function main() {
var integerArray = [1, 10, 2, 5, -1, 5, -19, 4, 23, 0];
var floatArray = [1.0, -3.2, 5.2, 10.8, -5.7, 7.3,
3.5, 0.0, -4.1, -9.5];
var stringArray = ['We', 'hold', 'these', 'truths', 'to',
'be', 'self-evident', 'that', 'all',
'men', 'are', 'created', 'equal'];
Sys.println('Unsorted Integers: ' + integerArray);
CocktailSort.sort(integerArray);
Sys.println('Sorted Integers: ' + integerArray);
Sys.println('Unsorted Floats: ' + floatArray);
CocktailSort.sort(floatArray);
Sys.println('Sorted Floats: ' + floatArray);
Sys.println('Unsorted Strings: ' + stringArray);
CocktailSort.sort(stringArray);
Sys.println('Sorted Strings: ' + stringArray);
}
}</syntaxhighlight>
 
{{out}}
<pre>
Unsorted Integers: [1,10,2,5,-1,5,-19,4,23,0]
Sorted Integers: [-19,-1,0,1,2,4,5,5,10,23]
Unsorted Floats: [1,-3.2,5.2,10.8,-5.7,7.3,3.5,0,-4.1,-9.5]
Sorted Floats: [-9.5,-5.7,-4.1,-3.2,0,1,3.5,5.2,7.3,10.8]
Unsorted Strings: [We,hold,these,truths,to,be,self-evident,that,all,men,are,created,equal]
Sorted Strings: [We,all,are,be,created,equal,hold,men,self-evident,that,these,to,truths]
</pre>
 
=={{header|Icon}} and {{header|Unicon}}==
<syntaxhighlight lang="icon">procedure main() #: demonstrate various ways to sort a list and string
demosort(cocktailsort,[3, 14, 1, 5, 9, 2, 6, 3],"qwerty")
end
 
procedure cocktailsort(X,op) #: return sorted list
local i,swapped
 
op := sortop(op,X) # select how and what we sort
 
swapped := 1
repeat # translation of pseudo code. Contractions used to eliminate second loop.
every (if /swapped then break break else swapped := &null & next) | ( i := 1 to *X-1) |
(if /swapped then break break else swapped := &null & next) | ( i := *X-1 to 1 by -1) do
if op(X[i+1],X[i]) then
X[i+1] :=: X[swapped := i]
return X
end</syntaxhighlight>
 
Note: This example relies on [[Sorting_algorithms/Bubble_sort#Icon| the supporting procedures 'sortop', and 'demosort' in Bubble Sort]].
The full demosort exercises the named sort of a list with op = "numeric", "string", ">>" (lexically gt, descending),">" (numerically gt, descending), a custom comparator, and also a string.
{{out|Abbreviated example output}}
<pre>Sorting Demo using procedure cocktailsort
on list : [ 3 14 1 5 9 2 6 3 ]
with op = &null: [ 1 2 3 3 5 6 9 14 ] (0 ms)
...
on string : "qwerty"
with op = &null: "eqrtwy" (0 ms)</pre>
 
=={{header|Io}}==
<langsyntaxhighlight lang="io">List do (
cocktailSortInPlace := method(
start := 0
Line 757 ⟶ 2,409:
 
l := list(2, 3, 4, 5, 1)
l cocktailSortInPlace println # ==> list(1, 2, 3, 4, 5)</langsyntaxhighlight>
 
=={{header|Icon}} and {{header|UniconIS-BASIC}}==
<syntaxhighlight lang="is-basic">100 PROGRAM "CocktSrt.bas"
<lang Icon>procedure main() #: demonstrate various ways to sort a list and string
110 RANDOMIZE
demosort(cocktailsort,[3, 14, 1, 5, 9, 2, 6, 3],"qwerty")
120 NUMERIC ARRAY(5 TO 24)
end
130 CALL INIT(ARRAY)
 
140 CALL WRITE(ARRAY)
procedure cocktailsort(X,op) #: return sorted list
150 CALL COCKTAILSORT(ARRAY)
local i,swapped
160 CALL WRITE(ARRAY)
 
170 DEF INIT(REF A)
op := sortop(op,X) # select how and what we sort
180 FOR I=LBOUND(A) TO UBOUND(A)
 
190 LET A(I)=RND(98)+1
swapped := 1
200 NEXT
repeat # translation of pseudo code. Contractions used to eliminate second loop.
210 END DEF
every (if /swapped then break break else swapped := &null & next) | ( i := 1 to *X-1) |
220 DEF WRITE(REF A)
(if /swapped then break break else swapped := &null & next) | ( i := *X-1 to 1 by -1) do
230 FOR I=LBOUND(A) TO UBOUND(A)
if op(X[i+1],X[i]) then
240 PRINT A(I);
X[i+1] :=: X[swapped := i]
250 NEXT
return X
260 PRINT
end</lang>
270 END DEF
 
280 DEF COCKTAILSORT(REF A)
Note: This example relies on [[Sorting_algorithms/Bubble_sort#Icon| the supporting procedures 'sortop', and 'demosort' in Bubble Sort]]. The full demosort exercises the named sort of a list with op = "numeric", "string", ">>" (lexically gt, descending),">" (numerically gt, descending), a custom comparator, and also a string.
290 LET ST=LBOUND(A)+1:LET EN=UBOUND(A):LET D,CH=1
 
300 DO
Abbreviated sample Output:<pre>Sorting Demo using procedure cocktailsort
310 on list : [FOR 3J=ST 14TO 1EN 5STEP 9 2 6 3 ]D
320 IF A(J-1)>A(J) THEN LET T=A(J-1):LET A(J-1)=A(J):LET A(J)=T:LET CH=J
with op = &null: [ 1 2 3 3 5 6 9 14 ] (0 ms)
330 NEXT
...
340 LET EN=ST:LET ST=CH-D:LET D=-1*D
on string : "qwerty"
350 LOOP UNTIL EN*D<ST*D
with op = &null: "eqrtwy" (0 ms)</pre>
360 END DEF</syntaxhighlight>
 
=={{header|J}}==
{{eff note|J|/:~}}
<langsyntaxhighlight lang="j">bigToLeft=: (([ (>. , <.) {.@]) , }.@])/
smallToLeft=: (([ (<. , >.) {.@]) , }.@])/
cocktailSort=: |. @: (|. @: smallToLeft @: |. @: bigToLeft ^:_)</langsyntaxhighlight>
 
Test run:
<syntaxhighlight lang="j"> ?. 10 $ 10
 
<lang j> ?. 10 $ 10
4 6 8 6 5 8 6 6 6 9
cocktailSort ?. 10 $ 10
4 5 6 6 6 6 6 8 8 9</langsyntaxhighlight>
 
As is usual with J, <code>/:~</code> is the preferred method of sorting in practice.
 
=={{header|Java}}==
This algorithm sorts in place. Call it with a copy of the array to preserve the unsorted order.
Call it with a copy of the array to preserve the unsorted order.
<lang java>public static void cocktailSort( int[] A ){
<syntaxhighlight lang="java">public static void cocktailSort( int[] A ){
boolean swapped;
do {
swapped = false;
for (int i =0; i<= A.length - 2;i++) {
if (A[ i ] > A[ i + 1 ]) {
//test whether the two elements are in the wrong order
Line 822 ⟶ 2,473:
}
swapped = false;
for (int i= A.length - 2;i>=0;i--) {
if (A[ i ] > A[ i + 1 ]) {
int temp = A[i];
A[i] = A[i+1];
Line 832 ⟶ 2,483:
//if no elements have been swapped, then the list is sorted
} while (swapped);
}</langsyntaxhighlight>
 
=={{header|LuaJavaScript}}==
<syntaxhighlight lang="javascript">
// Node 5.4.1 tested implementation (ES6)
"use strict";
 
let arr = [4, 9, 0, 3, 1, 5];
<lang Lua>
let isSorted = true;
function cocktailSort( A )
while (isSorted){
for (let i = 0; i< arr.length - 1;i++){
if (arr[i] > arr[i + 1])
{
let temp = arr[i];
arr[i] = arr[i + 1];
arr[i+1] = temp;
isSorted = true;
}
}
 
if (!isSorted)
break;
isSorted = false;
 
for (let j = arr.length - 1; j > 0; j--){
if (arr[j-1] > arr[j])
{
let temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
isSorted = true;
}
}
}
console.log(arr);
 
}</syntaxhighlight>
 
 
{{out}}
<pre>
[0, 1, 3, 4, 5, 9]
</pre>
 
=={{header|jq}}==
{{ works with|jq|1.4}}
<syntaxhighlight lang="jq"># In case your jq does not have "until" defined:
def until(cond; next):
def _until:
if cond then . else (next|_until) end;
_until;</syntaxhighlight>
<syntaxhighlight lang="jq">def cocktailSort:
def swap(i;j): .[i] as $t | .[i] = .[j] | .[j] = $t;
 
def shake(stream):
reduce stream as $i
(.[0]=false;
.[1] as $A
| if $A[ $i ] > $A[ $i+1 ] then
[true, ($A|swap( $i; $i+1 ))]
else .
end);
 
(length - 2) as $lm2
# state: [swapped, A]
| [true, .]
| until( .[0]|not;
shake(range(0; $lm2 + 1))
| if .[0] then
# for each i in length( A ) - 2 down to 0
shake( $lm2 - range(0; $lm2 + 1))
else .
end )
| .[1];</syntaxhighlight>
'''Tests:'''
<syntaxhighlight lang="jq">def verify: if cocktailSort == sort then empty else . end;
 
([],
[1],
[1,1],
[3, 14],
[33, 14],
[3, 14, 1, 5, 9, 2, 6, 3],
[23,76,99,58,97,57,35,89,51,38,95,92,24,46,31,24,14,12,57,78,4],
[88,18,31,44,4,0,8,81,14,78,20,76,84,33,73,75,82,5,62,70,12,7,1],
[1.5, -1.5],
["cocktail", ["sort"], null, {}]
) | verify</syntaxhighlight>
{{out}}
<syntaxhighlight lang="sh">$ jq -n -c -f cocktail_sort.jq
$</syntaxhighlight>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
<syntaxhighlight lang="julia">function cocktailsort(a::Vector)
b = copy(a)
isordered = false
lo, hi = 1, length(b)
while !isordered && hi > lo
isordered = true
for i in lo+1:hi
if b[i] < b[i-1]
b[i-1], b[i] = b[i], b[i-1]
isordered = false
end
end
hi -= 1
if isordered || hi ≤ lo break end
for i in hi:-1:lo+1
if b[i-1] > b[i]
b[i-1], b[i] = b[i], b[i-1]
isordered = false
end
end
lo += 1
end
return b
end
 
v = rand(-10:10, 10)
println("# unordered: $v\n -> ordered: ", cocktailsort(v))</syntaxhighlight>
 
{{out}}
<pre># unordered: [6, -9, 5, -10, 2, 4, 6, -6, -3, -8]
-> ordered: [-10, -9, -8, -6, -3, 2, 4, 5, 6, 6]</pre>
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.1.0
 
fun cocktailSort(a: IntArray) {
fun swap(i: Int, j: Int) {
val temp = a[i]
a[i] = a[j]
a[j] = temp
}
do {
var swapped = false
for (i in 0 until a.size - 1)
if (a[i] > a[i + 1]) {
swap(i, i + 1)
swapped = true
}
if (!swapped) break
swapped = false
for (i in a.size - 2 downTo 0)
if (a[i] > a[i + 1]) {
swap(i, i + 1)
swapped = true
}
}
while (swapped)
}
 
fun main(args: Array<String>) {
val aa = arrayOf(
intArrayOf(100, 2, 56, 200, -52, 3, 99, 33, 177, -199),
intArrayOf(4, 65, 2, -31, 0, 99, 2, 83, 782, 1),
intArrayOf(62, 83, 18, 53, 7, 17, 95, 86, 47, 69, 25, 28)
)
for (a in aa) {
cocktailSort(a)
println(a.joinToString(", "))
}
}</syntaxhighlight>
 
{{out}}
<pre>
-199, -52, 2, 3, 33, 56, 99, 100, 177, 200
-31, 0, 1, 2, 2, 4, 65, 83, 99, 782
7, 17, 18, 25, 28, 47, 53, 62, 69, 83, 86, 95
</pre>
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">function cocktailSort( A )
local swapped
repeat
Line 859 ⟶ 2,680:
 
until swapped==false
end</syntaxhighlight>
end
{{out|Example}}
 
<syntaxhighlight lang="lua">list = { 5, 6, 1, 2, 9, 14, 2, 15, 6, 7, 8, 97 }
</lang>
 
Example:
<lang lua>
list = { 5, 6, 1, 2, 9, 14, 2, 15, 6, 7, 8, 97 }
cocktailSort(list)
for i=1,#list do
print(list[i]j)
end</syntaxhighlight>
end
=={{header|M2000 Interpreter}}==
</lang>
<syntaxhighlight lang="m2000 interpreter">
Module cocktailSort {
k=(3,2,1)
print k
cocktailSort(k)
print k
k=("c","b","a")
print k
cocktailSortString(k)
print k
Dim a(5)
a(0)=1,2,5,6,3
print a()
cocktailSort(a())
print a()
End
Sub cocktailSort(a)
\\ this is like Link a to a() but using new for a() - shadow any a()
push &a : read new &a()
local swapped, lenA2=len(a)-2
do
for i=0 to lenA2
if a(i) > a(i+1) then swap a(i), a(i+1): swapped = true
next
if swapped then
swapped~
for i=lenA2 to 0
if a(i) > a(i+1) then swap a(i), a(i+1): swapped = true
next
end if
until not swapped
End Sub
Sub cocktailSortString(a)
push &a : read new &a$()
local swapped, lenA2=len(a)-2
do
for i=0 to lenA2
if a$(i) > a$(i+1) then
swap a$(i), a$(i+1)
swapped = true
end if
next
if swapped then
swapped~
for i=lenA2 to 0
if a$(i) > a$(i+1) then
swap a$(i), a$(i+1)
swapped = true
end if
next
end if
until not swapped
End Sub
}
cocktailSort
</syntaxhighlight>
{{out}}
<pre>
3 2 1
1 2 3
c b a
a b c
1 2 5 6 3
1 2 3 5 6
</pre>
 
=={{header|Maple}}==
<syntaxhighlight lang="maple">arr := Array([17,3,72,0,36,2,3,8,40,0]):
len := numelems(arr):
swap := proc(arr, a, b)
local temp := arr[a]:
arr[a] := arr[b]:
arr[b] := temp:
end proc:
while(true) do
swapped := false:
for i to len-1 do
if arr[i] > arr[i+1] then:
swap(arr, i, i+1):
swapped := true:
end if:
end do:
if (not swapped) then break: end if:
swapped := false:
for j from len-1 to 1 by -1 do
if arr[j] > arr[j+1] then
swap(arr,j,j+1):
swapped := true:
end if:
end do:
if (not swapped) then break: end if:
end do:
arr;</syntaxhighlight>
{{Output|Out}}
<pre>[0,0,2,3,3,8,17,36,40,72]</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">cocktailSort[A_List] := Module[ { swapped = True },
While[ swapped == True,
swapped=False;
Line 884 ⟶ 2,796:
For [ i= Length[A]-1, i > 0, i--,
If[ A[[i]] > A[[i+1]], A[[i;;i+1]] = A[[i+1;;i;;-1]]; swapped = True;]
]]]</langsyntaxhighlight>
{{out|Example}}
 
<pre>cocktailSort[{2,1,5,3,6}]
->{1,2,3,5,6}</pre>
 
=={{header|MATLAB}} / {{header|Octave}}==
<langsyntaxhighlight MATLABlang="matlab">function list = cocktailSort(list)
%We have to do this because the do...while loop doesn't exist in MATLAB
Line 919 ⟶ 2,831:
end %for
end %while
end %cocktail sort</langsyntaxhighlight>
{{out|Sample usage}}
 
<syntaxhighlight lang="matlab">cocktailSort([6 3 7 8 5 1 2 4 9])
Sample Usage:
<lang MATLAB>cocktailSort([6 3 7 8 5 1 2 4 9])
 
ans =
 
1 2 3 4 5 6 7 8 9</langsyntaxhighlight>
 
=={{header|MAXScript}}==
<langsyntaxhighlight lang="maxscript">fn cocktailSort arr =
(
local swapped = true
Line 954 ⟶ 2,865:
)
return arr
)</langsyntaxhighlight>
 
=={{header|NetRexx}}==
<langsyntaxhighlight NetRexxlang="netrexx">/* NetRexx */
options replace format comments java crossref savelog symbols binary
 
Line 994 ⟶ 2,905:
end i_
if \swapped then do
iterateleave swapped
end
swapped = isFalse
Line 1,013 ⟶ 2,924:
 
method isFalse public constant binary returns boolean
return \isTrue</syntaxhighlight>
{{out}}
</lang>
;Output
<pre>
UK London
Line 1,035 ⟶ 2,945:
US Washington
</pre>
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">template trySwap(): untyped =
if a[i] < a[i-1]:
swap a[i], a[i-1]
t = false
 
proc cocktailSort[T](a: var openarray[T]) =
var t = false
var l = a.len
while not t:
t = true
for i in 1 ..< l: trySwap
if t: break
for i in countdown(l-1, 1): trySwap
 
var a = @[4, 65, 2, -31, 0, 99, 2, 83, 782]
cocktailSort a
echo a</syntaxhighlight>
{{out}}
<pre>@[-31, 0, 2, 2, 4, 65, 83, 99, 782]</pre>
 
=={{header|Objeck}}==
<syntaxhighlight lang="objeck">bundle Default {
<lang objeck>
bundle Default {
class Cocktail {
function : Main(args : String[]) ~ Nil {
Line 1,079 ⟶ 3,009:
}
}
}</syntaxhighlight>
}
</lang>
 
=={{header|OCaml}}==
<langsyntaxhighlight lang="ocaml">let swap a i j =
let tmp = a.(i) in
a.(i) <- a.(j);
Line 1,119 ⟶ 3,048:
Array.iter (Printf.printf " %d") a;
print_newline();
;;</langsyntaxhighlight>
{{out}}
 
<pre>
outputs:
1 2 3 4 5 6 7 8 9
</pre>
 
=={{header|Octave}}==
<langsyntaxhighlight lang="octave">function sl = cocktailsort(l)
swapped = true;
while(swapped)
Line 1,151 ⟶ 3,081:
endwhile
sl = l;
endfunction</langsyntaxhighlight>
{{out|Example}}
 
<langsyntaxhighlight lang="octave">s = cocktailsort([5, -1, 101, -4, 0, \
1, 8, 6, 2, 3 ]);
disp(s);</langsyntaxhighlight>
 
=={{header|ooRexx}}==
{{Trans|NetRexx}}
<syntaxhighlight lang="oorexx">/* Rexx */
 
placesList = .array~of( -
"UK London", "US New York" , "US Boston", "US Washington" -
, "UK Washington", "US Birmingham" , "UK Birmingham", "UK Boston" -
)
 
sortedList = cocktailSort(placesList~allItems())
 
lists = .array~of(placesList, sortedList)
loop ln = 1 to lists~items()
cl = lists[ln]
loop ct = 1 to cl~items()
say cl[ct]
end ct
say
end ln
 
return
exit
 
::routine cocktailSort
use arg A
 
Alength = A~items()
swapped = .false
loop label swaps until \swapped
swapped = .false
loop i_ = 1 to Alength - 1
if A[i_] > A[i_ + 1] then do
swap = A[i_ + 1]
A[i_ + 1] = A[i_]
A[i_] = swap
swapped = .true
end
end i_
if \swapped then do
leave swaps
end
swapped = .false
loop i_ = Alength - 1 to 1 by -1
if A[i_] > A[i_ + 1] then do
swap = A[i_ + 1]
A[i_ + 1] = A[i_]
A[i_] = swap
swapped = .true
end
end i_
end swaps
 
return A</syntaxhighlight>
{{out}}
<pre>
UK London
US New York
US Boston
US Washington
UK Washington
US Birmingham
UK Birmingham
UK Boston
 
UK Birmingham
UK Boston
UK London
UK Washington
US Birmingham
US Boston
US New York
US Washington
</pre>
 
=={{header|Oz}}==
<langsyntaxhighlight lang="oz">declare
proc {CocktailSort Arr}
proc {Swap I J}
Line 1,183 ⟶ 3,187:
in
{CocktailSort Arr}
{Inspect Arr}</langsyntaxhighlight>
 
=={{header|PARI/GP}}==
<langsyntaxhighlight lang="parigp">cocktailSort(v)={
while(1,
my(done=1);
Line 1,209 ⟶ 3,213:
if(done, return(v))
)
};</langsyntaxhighlight>
 
 
=={{header|Pascal}}==
Line 1,217 ⟶ 3,219:
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">use strict;
use warnings;
use feature 'say';
 
sub cocktail_sort {
my @B=qw(t h e q u i c k b r o w n f o x j u m p s o v e r t h e l a z y d o g);
my @a = @_;
print "@B\n";
while (1) {
my @C=cocktailSort(@B);
print "@C\n";
################### cocktailSort #####################
sub cocktailSort { #( A : list of sortable items ) defined as:
my @A = @_;
my $swapped = 1;
while ($swapped == 1) {
$swapped = 0;
for (my $i=0; $i<($#A-1); $i+=1) {
 
if ($A[$i] gt $A[$i+1]) { # test whether the two
# elements are in the wrong
# order
 
($A[$i+1], $A[$i])=($A[$i], $A[$i+1]); # let the two elements
# change places
$swapped = 1;
}
}
if ($swapped == 0) {
# we can exit the outer loop here if no swaps occurred.
print "no more swaps";
}
else {
$swapped = 0;
for (my $i=($#A-1); $i>0 ; $i-=1) {
 
if($A[$i] gt $A[$i+1]) {
 
($A[$i+1], $A[$i])=($A[$i], $A[$i+1]);
$swapped = 1;
}
}
}
# if no elements have been swapped,
# then the list is sorted
}
return (@A);
#end sub
}</lang>
 
=={{header|Perl 6}}==
<lang perl6>sub cocktail_sort ( @a ) {
my $range = 0 ..^ @a.end;
loop {
my $swapped_forward = 0;
for $range.list ->my $i (0..$#a-1) {
if @($a[$i] >gt @$a[$i+1]) {
@a[ $i, $i+1 ] .= reverse@a[$i+1, $i];
$swapped_forward = 1;
}
}
last if not $swapped_forward;
 
my $swapped_backward = 0;
for my $range.i (reverse -> 0..$i#a-1) {
if @($a[$i] >gt @$a[$i+1]) {
@a[ $i, $i+1 ] .= reverse@a[$i+1, $i];
$swapped_backward = 1;
}
Line 1,285 ⟶ 3,244:
last if not $swapped_backward;
}
return @a;
}
 
say join ' ', cocktail_sort( <t h e q u i c k b r o w n f o x j u m p s o v e r t h e l a z y d o g> );</syntaxhighlight>
my @weights = (^50).map: { 100 + ( 1000.rand.Int / 10 ) };
{{out}}
say @weights.sort.Str eq @weights.&cocktail_sort.Str ?? 'ok' !! 'not ok';
<pre>a b c d e e e f g h h i j k l m n o o o o p q r r s t t u u v w x y z</pre>
</lang>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">cocktail_sort</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">swapped</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">f</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">swapped</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">swapped</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">f</span> <span style="color: #008080;">to</span> <span style="color: #000000;">t</span> <span style="color: #008080;">by</span> <span style="color: #000000;">d</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">si</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span>
<span style="color: #000000;">sn</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">si</span><span style="color: #0000FF;">></span><span style="color: #000000;">sn</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sn</span>
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">si</span>
<span style="color: #000000;">swapped</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000080;font-style:italic;">-- swap to and from, and flip direction.
-- additionally, we can reduce one element to be
-- examined, depending on which way we just went.</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">f</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">t</span><span style="color: #0000FF;">-</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">d</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">s</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_rand</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1000</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"original: %V\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">s</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" sorted: %V\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">cocktail_sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
original: {157,371,822,436,89,506,46,791,22,147}
sorted: {22,46,89,147,157,371,436,506,791,822}
</pre>
 
=={{header|PHP}}==
<langsyntaxhighlight lang="php">function cocktailSort($arr){
if (is_string($arr)) $arr = str_split(preg_replace('/\s+/','',$arr));
 
Line 1,330 ⟶ 3,325:
echo implode(',',$arr) . '<br>';
echo implode(',',$arr2) . '<br>';
echo implode('',$strg) . '<br>';</langsyntaxhighlight>
{{out}}
<pre>
1,2,3,4,5,6,7
Line 1,338 ⟶ 3,334:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de cocktailSort (Lst)
(use (Swapped L)
(loop
Line 1,356 ⟶ 3,352:
(on Swapped) )
(T (== Lst L)) )
(NIL Swapped Lst) ) ) )</langsyntaxhighlight>
{{out}}
Output:
<pre>: (cocktailSort (make (do 9 (link (rand 1 999)))))
-> (1 167 183 282 524 556 638 891 902)
Line 1,364 ⟶ 3,360:
 
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">cocktail: procedure (A);
<lang PL/I>
cocktail: procedure (A);
declare A(*) fixed;
declare t fixed;
Line 1,381 ⟶ 3,376:
end;
end;
end cocktail;</syntaxhighlight>
 
</lang>
=={{header|PowerShell}}==
Based on the entry for PowerShell in [[Bubble Sort]]
<langsyntaxhighlight PowerShelllang="powershell">function CocktailSort ($a) {
$l = $a.Length
$m = 0
Line 1,416 ⟶ 3,411:
}
 
$l = 10; CocktailSort ( 1..$l | ForEach-Object { $Rand = New-Object Random }{ $Rand.Next( -( $l - 1 ), $l - 1 ) } )</langsyntaxhighlight>
 
=={{header|Prolog}}==
<syntaxhighlight lang="prolog">ctail(_, [], Rev, Rev, sorted) :- write(Rev), nl.
ctail(fwrd, [A,B|T], In, Rev, unsorted) :- A > B, !,
ctail(fwrd, [B,A|T], In, Rev, _).
ctail(bkwd, [A,B|T], In, Rev, unsorted) :- A < B, !,
ctail(bkwd, [B,A|T], In, Rev, _).
ctail(D,[A|T], In, Rev, Ch) :- !, ctail(D, T, [A|In], Rev, Ch).
 
cocktail([], []).
cocktail(In, [Min|Out]) :-
ctail(fwrd, In, [], [Max|Rev], SFlag),
( SFlag=sorted->reverse([Max|Rev], [Min|Out]);
(ctail(bkwd, Rev, [Max], [Min|Tmp], SortFlag),
(SortFlag=sorted->Out=Tmp; !, cocktail(Tmp, Out)))).
 
test :- In = [8,9,1,3,4,2,6,5,4],
writef(' input=%w\n', [In]),
cocktail(In, R),
writef('-> %w\n', [R]).
</syntaxhighlight>
{{out|Example}}
<pre>?- test.
input=[8,9,1,3,4,2,6,5,4]
[9,4,5,6,2,4,3,1,8]
[1,8,2,3,4,4,6,5,9]
[9,8,5,6,4,4,3,2]
[2,3,4,4,5,6,8,9]
[9,8,6,5,4,4,3]
-> [1,2,3,4,4,5,6,8,9]
</pre>
 
=={{header|PureBasic}}==
The following approach improves on the method in the pseudo-code by not examining indexes on either end of the array that have already been sorted by reducing the index range on each subsequent pass.
<langsyntaxhighlight PureBasiclang="purebasic">;sorts an array of integers
Procedure cocktailSort(Array a(1))
Protected index, hasChanged, low, high
Line 1,450 ⟶ 3,476:
low + 1
Until hasChanged = #False ;if no elements have been changed, then the array is sorted
EndProcedure</langsyntaxhighlight>
 
=={{header|Python}}==
This implementation takes advantage of the identical processing of the two ''for'' loops and that a ''range'' is a first-class object in Python.<lang python>def cocktailSort(A):
<syntaxhighlight lang="python">def cocktailSort(A):
up = range(len(A)-1)
while True:
Line 1,463 ⟶ 3,490:
swapped = True
if not swapped:
return</langsyntaxhighlight>
{{out|Usage}}
 
<syntaxhighlight lang="python">test1 = [7, 6, 5, 9, 8, 4, 3, 1, 2, 0]
Usage:
<lang python>test1 = [7, 6, 5, 9, 8, 4, 3, 1, 2, 0]
cocktailSort(test1)
print test1
Line 1,474 ⟶ 3,500:
cocktailSort(test2)
print ''.join(test2)
#>>> abcdefghiijklmnopqrstuvwxyz</langsyntaxhighlight>
 
This implementation is clearer in structure to it's bubblesort origins while also being ever so slightly faster, in python 3.5.2 at least.
<syntaxhighlight lang="python">def cocktail(a):
for i in range(len(a)//2):
swap = False
for j in range(1+i, len(a)-i):
if a[j] < a[j-1]:
a[j], a[j-1] = a[j-1], a[j]
swap = True
if not swap:
break
swap = False
for j in range(len(a)-i-1, i, -1):
if a[j] < a[j-1]:
a[j], a[j-1] = a[j-1], a[j]
swap = True
if not swap:
break</syntaxhighlight>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="Quackery">
[ 2dup 1+ peek dip peek > ] is compare ( [ n --> b )
 
[ dup 1+ unrot
2dup peek
dip
[ 2dup 1+ peek
unrot poke
swap ]
unrot poke ] is exchange ( [ n --> [ )
 
[ [ 0 swap
dup size 1 - times
[ dup i^ compare if
[ i^ exchange
dip 1+ ] ]
over while
dup size 1 - times
[ dup i compare if
[ i exchange
dip 1+ ] ]
over while
nip again ]
nip ] is cocktail ( [ --> [ )
 
randomise
[] 20 times [ 89 random 10 + join ]
dup echo cr
cocktail echo</syntaxhighlight>
 
{{out}}
 
<pre>[ 46 42 73 92 95 19 27 52 33 12 60 70 34 45 93 15 64 41 12 55 ]
[ 12 12 15 19 27 33 34 41 42 45 46 52 55 60 64 70 73 92 93 95 ]</pre>
 
=={{header|R}}==
The previously solution missed out on a cool R trick for swapping items. As R is 1-indexed, we have made some minor adjustments to the given pseudo-code. Otherwise, we have aimed to be faithful to it.
<lang R>cocktailsort <- function(x)
<syntaxhighlight lang="rsplus">cocktailSort <- function(A)
{
repeat
lenx <- length(x)
repeat{
swapped <- FALSE
{
for(i in swappedseq_len(length(A) <- FALSE1))
{
for(i in 1:(lenx-1))
if(A[i] > A[i + 1])
{
if(xA[c(i, i + 1)] ><- xA[c(i + 1], i)]#The cool trick mentioned above.
swapped <- TRUE {
temp <- x[i]
x[i] <- x[i+1]
x[i+1] <- temp
swapped <- TRUE
}
}
}
if(!swapped) break
if(!swapped) break
swapped <- FALSE
for(i in (lenxlength(A)-1):1)
{
if(A[i] > A[i + 1])
{
if(xA[c(i, i + 1)] ><- xA[c(i + 1], i)]
swapped <- TRUE {
temp <- x[i]
x[i] <- x[i+1]
x[i+1] <- temp
swapped <- TRUE
}
}
}
if(!swapped) break
} if(!swapped) break
x }
A
}
#Examples taken from the Haxe solution.
ints <- c(1, 10, 2, 5, -1, 5, -19, 4, 23, 0)
numerics <- c(1, -3.2, 5.2, 10.8, -5.7, 7.3, 3.5, 0, -4.1, -9.5)
strings <- c("We", "hold", "these", "truths", "to", "be", "self-evident", "that", "all", "men", "are", "created", "equal")</syntaxhighlight>
 
{{out}}
print(cocktailsort(c(5, -1, 101, -4, 0, 1, 8, 6, 2, 3)))</lang>
<pre>> cocktailSort(ints)
[1] -19 -1 0 1 2 4 5 5 10 23
> cocktailSort(numerics)
[1] -9.5 -5.7 -4.1 -3.2 0.0 1.0 3.5 5.2 7.3 10.8
> cocktailSort(strings)
[1] "all" "are" "be" "created" "equal" "hold" "men"
[8] "self-evident" "that" "these" "to" "truths" "We"</pre>
 
=={{header|REXXRacket}}==
<syntaxhighlight lang="racket">
<lang rexx>
#lang racket
/*REXX program sorts an array using the cocktail-sort method. */
(require (only-in srfi/43 vector-swap!))
 
(define (cocktail-sort! xs)
call gen@ /*generate array elements. */
(define (ref i) (vector-ref xs i))
call show@ 'before sort' /*show before array elements*/
(define (swap i j) (vector-swap! xs i j))
call cocktailSort highItem /*invoke the cocktail sort. */
(define len (vector-length xs))
call show@ ' after sort' /*show after array elements*/
(define (bubble from to delta)
exit
(for/fold ([swaps 0]) ([i (in-range from to delta)])
(cond [(> (ref i) (ref (+ i 1)))
(swap i (+ i 1)) (+ swaps 1)]
[swaps])))
(let loop ()
(cond [(zero? (bubble 0 (- len 2) 1)) xs]
[(zero? (bubble (- len 2) 0 -1)) xs]
[(loop)])))
</syntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line>sub cocktail_sort ( @a ) {
my $range = 0 ..^ @a.end;
loop {
my $swapped_forward = 0;
for $range.list -> $i {
if @a[$i] > @a[$i+1] {
@a[ $i, $i+1 ] .= reverse;
$swapped_forward = 1;
}
}
last if not $swapped_forward;
 
my $swapped_backward = 0;
/*─────────────────────────────────────COCKTAILSORT subroutine─────*/
for $range.reverse -> $i {
cocktailSort: procedure expose @.; parse arg n
if @a[$i] > @a[$i+1] {
@a[ $i, $i+1 ] .= reverse;
$swapped_backward = 1;
}
}
last if not $swapped_backward;
}
return @a;
}
 
my @weights = (^50).map: { 100 + ( 1000.rand.Int / 10 ) };
do until done; done=1
say @weights.sort.Str eq @weights.&cocktail_sort.Str ?? 'ok' !! 'not ok';</syntaxhighlight>
 
=={{header|REXX}}==
do j=1 for n-1
===version handles blanks===
jp1=j+1
This REXX version can handle array elements that may contain blanks or spaces.
if @.j>@.jp1 then do; done=0; _=@.j; @.j=@.jp1; @.jp1=_; end
<syntaxhighlight lang="rexx">/*REXX program sorts an array using the cocktail─sort method, A.K.A.: happy hour sort,*/
end
/* bidirectional bubble sort, */
/* cocktail shaker sort, ripple sort,*/
/* a selection sort variation, */
/* shuffle sort, shuttle sort, or */
/* a bubble sort variation. */
call genItems /*generate some array elements. */
call showItems 'before sort' /*show unsorted array elements. */
say copies('█', 101) /*show a separator line (a fence). */
call cocktailSort /*invoke the cocktail sort subroutine. */
call showItems ' after sort' /*show sorted array elements. */
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
cocktailSort: procedure expose items.
nn = items.0 - 1 /*items.0: is number of items. */
do until done
done = 1
do j = 1 for nn
jp = j + 1 /* Rexx doesn't allow "items.(j+1)", so use this instead. */
if items.j > items.jp then do
done = 0
temp = items.j
items.j = items.jp
items.jp = temp
end
end /*j*/
if done then leave /*No swaps done? Finished*/
do k = nn for nn by -1
kp = k + 1 /* Rexx doesn't allow "items.(k+1)", so use this instead. */
if items.k > items.kp then do
done = 0
temp = items.k
items.k = items.kp
items.kp = temp
end
end /*k*/
end /*until*/
return
/*──────────────────────────────────────────────────────────────────────────────────────*/
genitems: procedure expose items.
items.= /*assign a default value for the stem. */
items.1 ='---the 22 card tarot deck (larger deck has 56 additional cards in 4 suits)---'
items.2 ='==========symbol====================pip======================================'
items.3 ='the juggler ◄─── I'
items.4 ='the high priestess [Popess] ◄─── II'
items.5 ='the empress ◄─── III'
items.6 ='the emperor ◄─── IV'
items.7 ='the hierophant [Pope] ◄─── V'
items.8 ='the lovers ◄─── VI'
items.9 ='the chariot ◄─── VII'
items.10='justice ◄─── VIII'
items.11='the hermit ◄─── IX'
items.12='fortune [the wheel of] ◄─── X'
items.13='strength ◄─── XI'
items.14='the hanging man ◄─── XII'
items.15='death [often unlabeled] ◄─── XIII'
items.16='temperance ◄─── XIV'
items.17='the devil ◄─── XV'
items.18='lightning [the tower] ◄─── XVI'
items.19='the stars ◄─── XVII'
items.20='the moon ◄─── XVIII'
items.21='the sun ◄─── XIX'
items.22='judgment ◄─── XX'
items.23='the world ◄─── XXI'
items.24='the fool [often unnumbered] ◄─── XXII'
items.0 =24 /* number of entries in the array. */
 
return
do k=n-1 by -1 for n-1
/*──────────────────────────────────────────────────────────────────────────────────────*/
kp1=k+1
showitems: procedure expose items.
if @.k>@.kp1 then do; done=0; _=@.k; @.k=@.kp1; @.kp1=_; end
endparse arg phase
width = length(items.0)
do j=1 to items.0 /* items.0 is the number of items in items. */
say 'element' right(j, width) phase || ":" items.j
end /*j*/ /* ↑ */
/* └─────max width of any line number. */
return</syntaxhighlight>
{{out|output|text=&nbsp; when using the internal default inputs:}}
 
(Shown at three-quarter size.)
end
<pre style="font-size:75%">
element 1 before sort: ---the 22 card tarot deck (larger deck has 56 additional cards in 4 suits)---
element 2 before sort: ==========symbol====================pip======================================
element 3 before sort: the juggler ◄─── I
element 4 before sort: the high priestess [Popess] ◄─── II
element 5 before sort: the empress ◄─── III
element 6 before sort: the emperor ◄─── IV
element 7 before sort: the hierophant [Pope] ◄─── V
element 8 before sort: the lovers ◄─── VI
element 9 before sort: the chariot ◄─── VII
element 10 before sort: justice ◄─── VIII
element 11 before sort: the hermit ◄─── IX
element 12 before sort: fortune [the wheel of] ◄─── X
element 13 before sort: strength ◄─── XI
element 14 before sort: the hanging man ◄─── XII
element 15 before sort: death [often unlabeled] ◄─── XIII
element 16 before sort: temperance ◄─── XIV
element 17 before sort: the devil ◄─── XV
element 18 before sort: lightning [the tower] ◄─── XVI
element 19 before sort: the stars ◄─── XVII
element 20 before sort: the moon ◄─── XVIII
element 21 before sort: the sun ◄─── XIX
element 22 before sort: judgment ◄─── XX
element 23 before sort: the world ◄─── XXI
element 24 before sort: the fool [often unnumbered] ◄─── XXII
█████████████████████████████████████████████████████████████████████████████████████████████████████
element 1 after sort: ---the 22 card tarot deck (larger deck has 56 additional cards in 4 suits)---
element 2 after sort: ==========symbol====================pip======================================
element 3 after sort: death [often unlabeled] ◄─── XIII
element 4 after sort: fortune [the wheel of] ◄─── X
element 5 after sort: judgment ◄─── XX
element 6 after sort: justice ◄─── VIII
element 7 after sort: lightning [the tower] ◄─── XVI
element 8 after sort: strength ◄─── XI
element 9 after sort: temperance ◄─── XIV
element 10 after sort: the chariot ◄─── VII
element 11 after sort: the devil ◄─── XV
element 12 after sort: the emperor ◄─── IV
element 13 after sort: the empress ◄─── III
element 14 after sort: the fool [often unnumbered] ◄─── XXII
element 15 after sort: the hanging man ◄─── XII
element 16 after sort: the hermit ◄─── IX
element 17 after sort: the hierophant [Pope] ◄─── V
element 18 after sort: the high priestess [Popess] ◄─── II
element 19 after sort: the juggler ◄─── I
element 20 after sort: the lovers ◄─── VI
element 21 after sort: the moon ◄─── XVIII
element 22 after sort: the stars ◄─── XVII
element 23 after sort: the sun ◄─── XIX
element 24 after sort: the world ◄─── XXI
</pre>
 
===version handles non-blanks===
return
This faster REXX version can handle array elements that don't contain blanks or spaces by using a simpler ''swap'' mechanism.
The REXX ''PARSE'' instruction separates an input into parts and assigns them to
variables, in a single operation. Thus
<syntaxhighlight lang="rexx">PARSE VALUE 0 items.j items.jp WITH done items.jp items.j</syntaxhighlight>
sets ''done'' to 0, ''items.jp'' to ''items.j'', and ''items.j'' to ''items.jp'', as long as none of the input
variables contain any blanks.
<syntaxhighlight lang="rexx">cocktailSort2: procedure expose items.
nn = items.0 - 1 /*N: the number of items in items.*/
do until done
done = 1
do j = 1 for nn
jp = j + 1 /* Rexx doesn't allow "items.(j+1)", so use this instead. */
if items.j > items.jp then ,
parse value 0 items.j items.jp with done items.jp items.j /* swap items.j and items.jp, and set done to 0 */
end /*j*/
if done then leave /*Did swaps? Then we're done.*/
do k = nn for nn by -1
kp = k + 1 /* Rexx doesn't allow "items.(k+1)", so use this instead. */
if items.k > items.kp then ,
parse value 0 items.k items.kp with done items.kp items.k /* swap items.k and items.kp, and set done to 0 */
end /*k*/
end /*until*/
 
return</syntaxhighlight> <br><br>
 
=={{header|Ring}}==
/*─────────────────────────────────────GEN@ subroutine─────────────*/
<syntaxhighlight lang="ring">
gen@: @.='' /*assign default value. */
aList = [ 5, 6, 1, 2, 9, 14, 2, 15, 6, 7, 8, 97]
flag = 0
cocktailSort(aList)
for i=1 to len(aList)
see "" + aList[i] + " "
next
 
func cocktailSort A
@.1 ='---the 22 card tarot deck (larger deck has 56 additional cards in 4 suits)---'
n = len(A)
@.2 ='==========symbol=====================pip====================================='
while flag = 0
@.3 ='the juggler ◄─── I'
flag = 1
@.4 ='the high priestess [Popess] ◄─── II'
@.5 ='the empress for i = ◄───1 to n-1 III'
@.6 ='the emperor if A[i] > ◄─── IV'A[i+1]
@.7 ='the hierophant [Pope] ◄─── V' temp = A[i]
@.8 ='the lovers A[i] = ◄─── VI'A[i+1]
@.9 ='the chariot A ◄─── [i+1] = VII'temp
@.10='justice flag = ◄─── VIII'0
@.11='the hermit ◄─── IX'ok
@.12='fortune [the wheel of] ◄─── X'next
end
@.13='stength ◄─── XI'
</syntaxhighlight>
@.14='the hanging man ◄─── XII'
@.15='death [often unlabeled] ◄─── XIII'
@.16='temperance ◄─── XIV'
@.17='the devel ◄─── XV'
@.18='lightning [the tower] ◄─── XVI'
@.18='the stars ◄─── XVII'
@.20='the moon ◄─── XVIII'
@.21='the sun ◄─── XIX'
@.22='judgment ◄─── XX'
@.23='the world ◄─── XXI'
@.24='the fool [often unnumbered] ◄─── XXII'
 
=={{header|RPL}}==
do highItem=1 while @.highItem\=='' /*find how many entries. */
{{works with|RPL|HP-49C}}
end
« '''DO''' 1 CF
1 OVER SIZE 1 - '''FOR''' h
DUP h DUP 1 + SUB
'''IF''' DUP EVAL > '''THEN'''
h SWAP REVLIST REPL
1 SF
'''ELSE''' DROP '''END'''
'''NEXT'''
'''IF''' 1 FS? '''THEN'''
DUP SIZE 1 - 1 '''FOR''' h
DUP h DUP 1 + SUB
'''IF''' DUP EVAL > '''THEN'''
h SWAP REVLIST REPL
1 SF
'''ELSE''' DROP '''END'''
-1 '''STEP'''
'''END'''
'''UNTIL''' 1 FC? '''END'''
» '<span style="color:blue">COCKTAILSORT</span>' STO
 
{ 7 6 5 9 8 4 3 1 2 0 } <span style="color:blue">COCKTAILSORT</span>
highItem=highItem-1 /*adjust highItem slightly. */
{{out}}
return
<pre>
 
1: { 0 1 2 3 4 5 6 7 8 9 }
 
/*─────────────────────────────────────SHOW@ subroutine────────────*/
show@: widthH=length(highItem) /*maximum width of any line.*/
 
do j=1 for highItem
say 'element' right(j,widthH) arg(1)":" @.j
end
 
say copies('─',80) /*show a seperator line. */
return
</lang>
Output:
<pre style="height:30ex;overflow:scroll">
element 1 before sort: ---the 22 card tarot deck (larger deck has 56 additional cards in 4 suits)---
element 2 before sort: ==========symbol=====================pip=====================================
element 3 before sort: the juggler ◄─── I
element 4 before sort: the high priestess [Popess] ◄─── II
element 5 before sort: the empress ◄─── III
element 6 before sort: the emperor ◄─── IV
element 7 before sort: the hierophant [Pope] ◄─── V
element 8 before sort: the lovers ◄─── VI
element 9 before sort: the chariot ◄─── VII
element 10 before sort: justice ◄─── VIII
element 11 before sort: the hermit ◄─── IX
element 12 before sort: fortune [the wheel of] ◄─── X
element 13 before sort: stength ◄─── XI
element 14 before sort: the hanging man ◄─── XII
element 15 before sort: death [often unlabeled] ◄─── XIII
element 16 before sort: temperance ◄─── XIV
element 17 before sort: the devel ◄─── XV
element 18 before sort: the stars ◄─── XVII
────────────────────────────────────────────────────────────────────────────────
element 1 after sort: ---the 22 card tarot deck (larger deck has 56 additional cards in 4 suits)---
element 2 after sort: ==========symbol=====================pip=====================================
element 3 after sort: death [often unlabeled] ◄─── XIII
element 4 after sort: fortune [the wheel of] ◄─── X
element 5 after sort: justice ◄─── VIII
element 6 after sort: stength ◄─── XI
element 7 after sort: temperance ◄─── XIV
element 8 after sort: the chariot ◄─── VII
element 9 after sort: the devel ◄─── XV
element 10 after sort: the emperor ◄─── IV
element 11 after sort: the empress ◄─── III
element 12 after sort: the hanging man ◄─── XII
element 13 after sort: the hermit ◄─── IX
element 14 after sort: the hierophant [Pope] ◄─── V
element 15 after sort: the high priestess [Popess] ◄─── II
element 16 after sort: the juggler ◄─── I
element 17 after sort: the lovers ◄─── VI
element 18 after sort: the stars ◄─── XVII
────────────────────────────────────────────────────────────────────────────────
</pre>
This implementation is 40 times slower than the built-in <code>SORT</code> function on an HP-50g.
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">class Array
def cocktailsort!
begin
Line 1,642 ⟶ 3,875:
end
end
break if notunless swapped
swapped = false
Line 1,654 ⟶ 3,887:
self
end
end</syntaxhighlight>
end
 
ary = [7,6,5,9,8,4,3,1,2,0]
Another way
ary.cocktailsort!
<syntaxhighlight lang="ruby">class Array
# => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]</lang>
def cocktailsort!
start, finish, way = 0, size-1, 1
loop do
swapped = false
start.step(finish-way, way) do |i|
if (self[i] <=> self[i + way]) == way
self[i], self[i + way] = self[i + way], self[i]
swapped = i
end
end
break unless swapped
start, finish, way = swapped, start, -way
end
self
end
end</syntaxhighlight>
 
Test:
<syntaxhighlight lang="ruby">ary = [7,6,5,9,8,4,3,1,2,0]
p ary.cocktailsort!
ary = ["John", "Kate", "Zerg", "Alice", "Joe", "Jane"]
p ary.cocktailsort!</syntaxhighlight>
 
{{out}}
<pre>
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
["Alice", "Jane", "Joe", "John", "Kate", "Zerg"]
</pre>
 
=={{header|Run BASIC}}==
<syntaxhighlight lang="runbasic">for i = 1 to 100 ' fill array
a(i) = rnd(0) * 100
next i
' ------- sort -------
beg = 2
siz = 100
whatWay = 1
changed = 1
while changed
changed = 0
FOR i = beg TO siz STEP whatWay
IF a(i-1) > a(i) THEN
hold = a(i)
a(i) = a(i-1)
a(i-1) = hold
changed = i
end if
NEXT i
siz = beg
beg = changed - whatWay
whatWay = 0 - whatWay
wend
' ------ print result --------
for i = 1 to 100
print i;" ";a(i)
next i
end</syntaxhighlight>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">fn cocktail_sort<T: PartialOrd>(a: &mut [T]) {
let len = a.len();
loop {
let mut swapped = false;
let mut i = 0;
while i + 1 < len {
if a[i] > a[i + 1] {
a.swap(i, i + 1);
swapped = true;
}
i += 1;
}
if swapped {
swapped = false;
i = len - 1;
while i > 0 {
if a[i - 1] > a[i] {
a.swap(i - 1, i);
swapped = true;
}
i -= 1;
}
}
if !swapped {
break;
}
}
}
 
fn main() {
let mut v = vec![10, 8, 4, 3, 1, 9, 0, 2, 7, 5, 6];
println!("before: {:?}", v);
cocktail_sort(&mut v);
println!("after: {:?}", v);
}</syntaxhighlight>
 
{{out}}
<pre>
before: [10, 8, 4, 3, 1, 9, 0, 2, 7, 5, 6]
after: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
</pre>
 
=={{header|Scala}}==
<syntaxhighlight lang="scala">object CocktailSort extends App {
def sort(arr: Array[Int]) = {
var swapped = false
do {
def swap(i: Int) {
val temp = arr(i)
arr(i) = arr(i + 1)
arr(i + 1) = temp
swapped = true
}
 
swapped = false
for (i <- 0 to (arr.length - 2)) if (arr(i) > arr(i + 1)) swap(i)
 
if (swapped) {
swapped = false
for (j <- arr.length - 2 to 0 by -1) if (arr(j) > arr(j + 1)) swap(j)
//if no elements have been swapped, then the list is sorted
}
} while (swapped)
arr
}
 
println(sort(Array(170, 45, 75, -90, -802, 24, 2, 66)).mkString(", "))
 
}</syntaxhighlight>
 
=={{header|Scilab}}==
<syntaxhighlight lang="text">function varargout=cocktailSort(list_in)
swapped = %T;
while swapped
swapped = %F;
for i = [1:length(list_in)-1]
if list_in(i) > list_in(i+1) then
list_in([i i+1])=list_in([i+1 i]);
swapped = %T;
end
end
if ~swapped
break
end
swapped = %F;
for i = [length(list_in)-1:-1:1]
if list_in(i) > list_in(i+1)
list_in([i i+1]) = list_in([i+1 i])
swapped = %T;
end
end
end
varargout=list(list_in)
endfunction
 
disp(cocktailSort([6 3 7 8 5 1 2 4 9]));</syntaxhighlight>
{{out}}
<pre> 1. 2. 3. 4. 5. 6. 7. 8. 9.</pre>
 
=={{header|Seed7}}==
<syntaxhighlight lang="seed7">const proc: cocktailSort (inout array elemType: arr) is func
local
var boolean: swapped is FALSE;
var integer: i is 0;
var elemType: help is elemType.value;
begin
repeat
swapped := FALSE;
for i range 1 to length(arr) - 1 do
if arr[i] > arr[i + 1] then
help := arr[i];
arr[i] := arr[i + 1];
arr[i + 1] := help;
swapped := TRUE;
end if;
end for;
if swapped then
swapped := FALSE;
for i range length(arr) - 1 downto 1 do
if arr[i] > arr[i + 1] then
help := arr[i];
arr[i] := arr[i + 1];
arr[i + 1] := help;
swapped := TRUE;
end if;
end for;
end if;
until not swapped;
end func;</syntaxhighlight>
 
Original source: [http://seed7.sourceforge.net/algorith/sorting.htm#cocktailSort]
 
=={{header|Sidef}}==
<syntaxhighlight lang="ruby">func cocktailsort(a) {
var swapped = false
func cmpsw(i) {
if (a[i] > a[i+1]) {
a[i, i+1] = a[i+1, i]
swapped = true
}
}
var max = a.end
do {
{|i| cmpsw(i) } << ^max
swapped.not! && break
{|i| cmpsw(max-i) } << 1..max
} while (swapped)
return a
}</syntaxhighlight>
Test:
<syntaxhighlight lang="ruby">var numbers = [7,6,5,9,8,4,3,1,2,0]
say cocktailsort(numbers)
 
var strs = ["John", "Kate", "Zerg", "Alice", "Joe", "Jane"]
say cocktailsort(strs)</syntaxhighlight>
{{out}}
<pre>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
['Alice', 'Jane', 'Joe', 'John', 'Kate', 'Zerg']</pre>
 
=={{header|Slate}}==
<langsyntaxhighlight lang="slate">s@(Sequence traits) cocktailSort
[ |swapped|
swapped: False.
Line 1,669 ⟶ 4,119:
swapped: False].
] loop
].</langsyntaxhighlight>
{{out|Example}}
 
<langsyntaxhighlight lang="slate">slate[1]> #( 10 9 8 7 6 0 -5) cocktailSort.
{-5. 0. 6. 7. 8. 9. 10}</langsyntaxhighlight>
 
=={{header|Smalltalk}}==
{{works with|GNU Smalltalk}}
<langsyntaxhighlight lang="smalltalk">OrderedCollection extend [
swap: indexA and: indexB [
|t|
Line 1,705 ⟶ 4,155:
^ self
]
].</langsyntaxhighlight>
{{out|Example}}
<syntaxhighlight lang="smalltalk">(#( 10 9 8 7 6 0 -5) asOrderedCollection cocktailSort) printNl.</syntaxhighlight>
 
=={{header|Swift}}==
<lang smalltalk>(#( 10 9 8 7 6 0 -5) asOrderedCollection cocktailSort) printNl.</lang>
 
<syntaxhighlight lang="swift">extension Collection where Element: Comparable {
public func cocktailSorted() -> [Element] {
var swapped = false
var ret = Array(self)
 
guard count > 1 else {
return ret
}
repeat {
for i in 0...ret.count-2 where ret[i] > ret[i + 1] {
(ret[i], ret[i + 1]) = (ret[i + 1], ret[i])
swapped = true
}
 
guard swapped else {
break
}
 
swapped = false
 
for i in stride(from: ret.count - 2, through: 0, by: -1) where ret[i] > ret[i + 1] {
(ret[i], ret[i + 1]) = (ret[i + 1], ret[i])
swapped = true
}
} while swapped
 
return ret
}
}
 
let arr = (1...10).shuffled()
 
print("Before: \(arr)")
print("Cocktail sort: \(arr.cocktailSorted())")</syntaxhighlight>
 
{{out}}
 
<pre>Before: [5, 4, 7, 10, 9, 8, 1, 6, 2, 3]
Cocktail sort: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]</pre>
 
=={{header|Tcl}}==
{{tcllib|struct::list}}<!-- convenient element swapping only -->
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
package require struct::list
 
Line 1,739 ⟶ 4,232:
}
return $A
}</syntaxhighlight>
}
{{out|Example}}
<syntaxhighlight lang="tcl">puts [cocktailsort {8 6 4 2 1 3 5 7 9}] ;# => 1 2 3 4 5 6 7 8 9</syntaxhighlight>
 
=={{header|uBasic/4tH}}==
puts [cocktailsort {8 6 4 2 1 3 5 7 9}] ;# => 1 2 3 4 5 6 7 8 9</lang>
<syntaxhighlight lang="text">PRINT "Cocktail sort:"
n = FUNC (_InitArray)
PROC _ShowArray (n)
PROC _Cocktailsort (n)
PROC _ShowArray (n)
PRINT
END
 
 
_Cocktailsort PARAM (1) ' Cocktail sort
LOCAL (2)
b@ = 0
 
DO WHILE b@ = 0
b@ = 1
FOR c@=1 TO a@-1
IF @(c@) < @(c@-1) THEN PROC _Swap (c@, c@-1) : b@ = 0
NEXT
UNTIL b@
b@ = 1
FOR c@=a@-1 TO 1 STEP -1
IF @(c@) < @(c@-1) THEN PROC _Swap (c@, c@-1) : b@ = 0
NEXT
LOOP
RETURN
_Swap PARAM(2) ' Swap two array elements
PUSH @(a@)
@(a@) = @(b@)
@(b@) = POP()
RETURN
_InitArray ' Init example array
PUSH 4, 65, 2, -31, 0, 99, 2, 83, 782, 1
FOR i = 0 TO 9
@(i) = POP()
NEXT
RETURN (i)
_ShowArray PARAM (1) ' Show array subroutine
FOR i = 0 TO a@-1
PRINT @(i),
NEXT
PRINT
RETURN</syntaxhighlight>
 
=={{header|Ursala}}==
The same function is used for the traversal in each direction, in one case parameterized by the given predicate and in the other by its negation. Lists are used rather than arrays. The fold combinator (<code>=></code>) avoids explicit recursion.
<syntaxhighlight lang="ursala">#import std
predicate and in the other by its negation. Lists are used rather than arrays. The fold combinator
(=>) avoids explicit recursion.
<lang Ursala>#import std
 
ctsort = ^=+ +^|(==?/~&l+ @r+ ~&x++ @x,^/~&)+ ("p". =><> ~&r?\~&C "p"?lrhPX/~&C ~&rhPlrtPCC)^~/not ~&</langsyntaxhighlight>
test program:
<langsyntaxhighlight Ursalalang="ursala">#cast %s
 
test = ctsort(lleq) 'mdfdguldxisgbxjtqkadfkslakwkyioukdledbig'</langsyntaxhighlight>
{{out}}
output:
<pre>
'aabbddddddeffgggiiijkkkkklllmoqsstuuwxxy'
</pre>
 
=={{header|Vala}}==
{{trans|C}}
<syntaxhighlight lang="vala">void swap(int[] array, int i1, int i2) {
if (array[i1] == array[i2])
return;
var tmp = array[i1];
array[i1] = array[i2];
array[i2] = tmp;
}
 
void cocktail_sort(int[] array) {
while(true) {
bool flag = false;
int[] start = {1, array.length - 1};
int[] end = {array.length, 0};
int[] inc = {1, -1};
for (int it = 0; it < 2; ++it) {
flag = true;
for (int i = start[it]; i != end[it]; i += inc[it])
if (array[i - 1] > array[i]) {
swap(array, i - 1, i);
flag = false;
}
}
if (flag) return;
}
}
 
void main() {
int[] array = {5, -1, 101, -4, 0, 1, 8, 6, 2, 3};
cocktail_sort(array);
foreach (int i in array) {
stdout.printf("%d ", i);
}
}</syntaxhighlight>
 
{{out}}
<pre>
-4 -1 0 1 2 3 5 6 8 101
</pre>
 
=={{header|VBA}}==
{{trans|Phix}}<syntaxhighlight lang="vb">Function cocktail_sort(ByVal s As Variant) As Variant
Dim swapped As Boolean
Dim f As Integer, t As Integer, d As Integer, tmp As Integer
swapped = True
f = 1
t = UBound(s) - 1
d = 1
Do While swapped
swapped = 0
For i = f To t Step d
If Val(s(i)) > Val(s(i + 1)) Then
tmp = s(i)
s(i) = s(i + 1)
s(i + 1) = tmp
swapped = True
End If
Next i
'-- swap to and from, and flip direction.
'-- additionally, we can reduce one element to be
'-- examined, depending on which way we just went.
tmp = f
f = t + (d = 1)
t = tmp + (d = -1)
d = -d
Loop
cocktail_sort = s
End Function
Public Sub main()
Dim s(9) As Variant
For i = 0 To 9
s(i) = CStr(Int(1000 * Rnd))
Next i
Debug.Print Join(s, ", ")
Debug.Print Join(cocktail_sort(s), ", ")
End Sub</syntaxhighlight>{{out}}
<pre>45, 414, 862, 790, 373, 961, 871, 56, 949, 364
45, 56, 364, 373, 414, 790, 862, 871, 949, 961</pre>
 
=={{header|VBScript}}==
A few of the streets nearby.
 
=====;Implementation=====
<syntaxhighlight lang="vb">function cocktailSort( byval a )
<lang vb>
function cocktailSort( a )
dim swapped
dim i
Line 1,793 ⟶ 4,418:
a = b
b = tmp
end sub</syntaxhighlight>
;Invocation
</lang>
<syntaxhighlight lang="vb">dim a
 
=====Invocation=====
<lang vb>
dim a
a = array( "portcullis", "redoubt", "palissade", "turret", "collins", "the parapet", "the quarterdeck")
wscript.echo join( a, ", ")
Line 1,804 ⟶ 4,426:
dim b
b = cocktailSort( a )
wscript.echo join( b, ", ")</syntaxhighlight>
{{out}}
</lang>
 
=====Output=====
<pre>
portcullis, redoubt, palissade, turret, collins, the parapet, the quarterdeck
collins, palissade, portcullis, redoubt, the parapet, the quarterdeck, turret
</pre>
 
=={{header|V (Vlang)}}==
<syntaxhighlight lang="v (vlang)">fn cocktail(mut arr []int) {
input := 'Input'
output := 'Output'
println('${input : -7s}: ${arr.str()}')
for {
mut swapped := false
for i := 0; i < arr.len - 1; i++ {
if arr[i] > arr[i + 1] {
temp := arr[i]
arr[i] = arr[i + 1]
arr[i + 1] = temp
swapped = true
}
}
if !swapped {
break
}
swapped = false
for i := arr.len - 2; i >= 0; i-- {
if arr[i] > arr[i + 1] {
temp := arr[i]
arr[i] = arr[i + 1]
arr[i + 1] = temp
swapped = true
}
}
if !swapped {
break
}
}
println('${output : -7s}: ${arr.str()}')
}
 
fn main() {
mut arr := [6, 9, 1, 4]
cocktail(mut arr)
arr = [-8, 15, 1, 4, -3, 20]
cocktail(mut arr)
}</syntaxhighlight>
{{out}}
<pre>Input : [6, 9, 1, 4]
Output : [1, 4, 6, 9]
Input : [-8, 15, 1, 4, -3, 20]
Output : [-8, -3, 1, 4, 15, 20]</pre>
 
=={{header|Wren}}==
{{trans|Go}}
<syntaxhighlight lang="wren">var cocktailSort = Fn.new { |a|
var last = a.count - 1
while (true) {
var swapped = false
for (i in 0...last) {
if (a[i] > a[i+1]) {
var t = a[i]
a[i] = a[i+1]
a[i+1] = t
swapped = true
}
}
if (!swapped) return
swapped = false
if (last >= 1) {
for (i in last-1..0) {
if (a[i] > a[i+1]) {
var t = a[i]
a[i] = a[i+1]
a[i+1] = t
swapped = true
}
}
}
if (!swapped) return
}
}
 
var a = [170, 45, 75, -90, -802, 24, 2, 66]
System.print("Before: %(a)")
cocktailSort.call(a)
System.print("After : %(a)")</syntaxhighlight>
 
{{out}}
<pre>
Before: [170, 45, 75, -90, -802, 24, 2, 66]
After : [-802, -90, 2, 24, 45, 66, 75, 170]
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang="xpl0">code ChOut=8, IntOut=11;
 
proc CocktailSort(A, L); \Sort array A of length L
int A, L;
int Swapped, I, T;
[loop [Swapped:= false;
for I:= 0 to L-2 do
if A(I) > A(I+1) then \test if elements are in wrong order
[T:= A(I); A(I):= A(I+1); A(I+1):= T; \elements change places
Swapped:= true;
];
if Swapped = false then quit; \exit outer loop if no swaps occurred
Swapped:= false;
for I:= L-2 downto 0 do
if A(I) > A(I+1) then
[T:= A(I); A(I):= A(I+1); A(I+1):= T;
Swapped:= true;
];
\if no elements have been swapped then the list is sorted
if not Swapped then quit;
];
];
 
int A, I;
[A:= [3, 1, 4, 1, -5, 9, 2, 6, 5, 4];
CocktailSort(A, 10);
for I:= 0 to 10-1 do [IntOut(0, A(I)); ChOut(0, ^ )];
]</syntaxhighlight>
 
{{out}}
<pre>
-5 1 1 2 3 4 4 5 6 9
</pre>
 
=={{header|zkl}}==
This has the Wikipedia optimizations.
<syntaxhighlight lang="zkl">fcn cocktailSort(a){
swapped,begin,end:=False,-1,a.len() - 2;
do{
swapped,begin=False,begin + 1;
foreach i in ([begin .. end]){
if(a[i]>a[i+1]){ a.swap(i,i+1); swapped=True; }
}
if(not swapped) break;
swapped,end=False,end - 1;
foreach i in ([end..begin,-1]){
if(a[i]>a[i+1]){ a.swap(i,i+1); swapped=True; }
}
}while(swapped);
a
}</syntaxhighlight>
<syntaxhighlight lang="zkl">cocktailSort(List(2,1)).println();
x:=List(5, -1, 101, -4, 0, 1, 8, 6, 2, 3 );
cocktailSort(x).println();
x="the lazy fox jumped over the brown dog".split(" ").copy();
cocktailSort(x).println();</syntaxhighlight>
{{out}}
<pre>
L(1,2)
L(-4,-1,0,1,2,3,5,6,8,101)
L("brown","dog","fox","jumped","lazy","over","the","the"
</pre>
 
=={{header|ZX Spectrum Basic}}==
its a "cocktail" bubble sort, but the writer called it 'zigzag' since the name was unknown
<syntaxhighlight lang="zxbasic">5000 CLS
5002 LET a$="": FOR f=1 TO 64: LET a$=a$+CHR$ (32+INT (RND*96)): NEXT f
5004 PRINT a$; AT 10,0;"ZigZag BubbleSORT"
5010 LET la=LEN a$
5011 LET i=1: LET u=0
5020 LET d=0: LET p=(u=0)-(u=1)
5021 LET l=(i AND u=0)+(la-i+u AND u=1)
5030 IF u=0 THEN IF a$(l+1)>=a$(l) THEN GO TO 5050
5031 IF u=1 THEN IF a$(l-1)<=a$(l) THEN GO TO 5050
5040 LET d=1
5042 LET t$=a$(l+p)
5043 LET a$(l+p)=a$(l)
5044 LET a$(l)=t$
5050 LET l=l+p
5051 PRINT AT 10,21;a$(l);AT 12,0;a$
5055 IF l<=la-i AND l>=i THEN GO TO 5023
5061 LET i=i+NOT u
5063 LET u=NOT u
5064 IF d AND i<la THEN GO TO 5020
5072 PRINT AT 12,0;a$
9000 STOP</syntaxhighlight>
Next is an optimisation by using the margin value's as swop comparative aswell
so its swops inside and at the edges from the file
 
its a " Sticky (edge) Cocktail Sort"
By C. Born (freeware)
<syntaxhighlight lang="zxbasic">5000 CLS : PRINT ;"Jumping Zig Zag BubbleSORT"'"aka Sticky Cocktail Sort"
5002 LET a$="": FOR f=1 TO 96: LET a$=a$+CHR$ (48+INT (RND*48)): NEXT f
5004 PRINT 'a$
5010 LET a=LEN a$: LET i=1: LET u=0: LET up=0: LET do=0
 
5020 LET d=0: LET p=(NOT u)-u: LET l=(i AND NOT u)+(a AND u)
 
5030 IF NOT u THEN IF a$(l+1)>=a$(l) THEN GO TO 5060
5031 IF u THEN IF a$(l-1)<=a$(l) THEN GO TO 5060
5040 LET w=l+p: GO SUB 5400
 
5060 IF up THEN IF a<LEN a$ THEN IF a$(l)=a$(a+1) THEN LET w=a: GO SUB 5400: GO SUB 5500
5061 IF do THEN IF i>1 THEN IF a$(l)=a$(i-1) THEN LET w=i: GO SUB 5400: GO SUB 5500
 
5100 LET l=l+p
5150 PRINT AT 10,0;a$(l);AT 12,0;a$
5151 PRINT AT 21,0;i;a$(i),a;a$(a)
5155 IF NOT u THEN IF l<a THEN GO TO 5030
5156 IF u THEN IF l>i THEN GO TO 5030
 
5170 LET do=up=1: LET up=1
5261 LET i=i+u: LET a=a-NOT u: LET u=NOT u
5264 IF d AND i<a THEN GO TO 5020
 
5272 PRINT AT 12,0;a$
5399 STOP
 
5400 LET d=1: LET t$=a$(w): LET a$(w)=a$(l): LET a$(l)=t$: RETURN
 
5500 IF a+1<=LEN a$ THEN IF a$(a)=a$(a+1) THEN LET a=a-1: GO TO 5500
5510 IF i-1>=1 THEN IF a$(i)=a$(i-1) THEN LET i=i+1: GO TO 5500
5520 RETURN
9999 CLEAR : SAVE "JZZB" LINE 0</syntaxhighlight>
 
{{omit from|GUISS}}
1,150

edits