Initial data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 72d218235f
commit f23f22d71c
199087 changed files with 3378941 additions and 0 deletions

View file

@ -0,0 +1,3 @@
---
from: http://rosettacode.org/wiki/Sorting_algorithms/Merge_sort
note: Sorting Algorithms

View file

@ -0,0 +1,65 @@
{{Sorting Algorithm}}
[[Category:Sorting]]
[[Category:Recursion]]
The &nbsp; '''merge sort''' &nbsp; is a recursive sort of order &nbsp; <big> n*log(n). </big>
It is notable for having a worst case and average complexity of &nbsp; <big> ''O(n*log(n))'', </big> &nbsp; and a best case complexity of &nbsp; <big> ''O(n)'' &nbsp; </big> (for pre-sorted input).
The basic idea is to split the collection into smaller groups by halving it until the groups only have one element or no elements &nbsp; (which are both entirely sorted groups).
Then merge the groups back together so that their elements are in order.
This is how the algorithm gets its &nbsp; ''divide and conquer'' &nbsp; description.
;Task:
Write a function to sort a collection of integers using the merge sort.
The merge sort algorithm comes in two parts:
a sort function and
a merge function
The functions in pseudocode look like this:
'''function''' ''mergesort''(m)
'''var''' list left, right, result
'''if''' length(m) ≤ 1
'''return''' m
'''else'''
'''var''' middle = length(m) / 2
'''for each''' x '''in''' m '''up to''' middle - 1
'''add''' x '''to''' left
'''for each''' x '''in''' m '''at and after''' middle
'''add''' x '''to''' right
left = mergesort(left)
right = mergesort(right)
'''if''' last(left) ≤ first(right)
'''append''' right '''to''' left
'''return''' left
result = merge(left, right)
'''return''' result
'''function''' ''merge''(left,right)
'''var''' list result
'''while''' length(left) > 0 and length(right) > 0
'''if''' first(left) ≤ first(right)
'''append''' first(left) '''to''' result
left = rest(left)
'''else'''
'''append''' first(right) '''to''' result
right = rest(right)
'''if''' length(left) > 0
'''append''' rest(left) '''to''' result
'''if''' length(right) > 0
'''append''' rest(right) '''to''' result
'''return''' result
;See also:
* &nbsp; the Wikipedia entry: &nbsp; [[wp:Merge_sort| merge sort]]
Note: &nbsp; better performance can be expected if, rather than recursing until &nbsp; <big> length(m) ≤ 1, </big> &nbsp; an insertion sort is used for &nbsp; <big> length(m) </big> &nbsp; smaller than some threshold larger than &nbsp; '''1'''. &nbsp; However, this complicates the example code, so it is not shown here.
<br><br>

View file

@ -0,0 +1,32 @@
F merge(left, right)
[Int] result
V left_idx = 0
V right_idx = 0
L left_idx < left.len & right_idx < right.len
I left[left_idx] <= right[right_idx]
result.append(left[left_idx])
left_idx++
E
result.append(right[right_idx])
right_idx++
I left_idx < left.len
result.extend(left[left_idx ..])
I right_idx < right.len
result.extend(right[right_idx ..])
R result
F merge_sort(m)
I m.len <= 1
R m
V middle = m.len I/ 2
V left = m[0.<middle]
V right = m[middle..]
left = merge_sort(left)
right = merge_sort(right)
R Array(merge(left, right))
V arr = [7, 6, 5, 9, 8, 4, 3, 1, 2, 0]
print(merge_sort(arr))

View file

@ -0,0 +1,164 @@
* Merge sort 19/06/2016
MAIN CSECT
STM R14,R12,12(R13) save caller's registers
LR R12,R15 set R12 as base register
USING MAIN,R12 notify assembler
LA R11,SAVEXA get the address of my savearea
ST R13,4(R11) save caller's save area pointer
ST R11,8(R13) save my save area pointer
LR R13,R11 set R13 to point to my save area
LA R1,1 1
LA R2,NN hbound(a)
BAL R14,SPLIT call split(1,hbound(a))
LA RPGI,PG pgi=0
LA RI,1 i=1
DO WHILE=(C,RI,LE,=A(NN)) do i=1 to hbound(a)
LR R1,RI i
SLA R1,2 .
L R2,A-4(R1) a(i)
XDECO R2,XDEC edit a(i)
MVC 0(4,RPGI),XDEC+8 output a(i)
LA RPGI,4(RPGI) pgi=pgi+4
LA RI,1(RI) i=i+1
ENDDO , end do
XPRNT PG,80 print buffer
L R13,SAVEXA+4 restore caller's savearea address
LM R14,R12,12(R13) restore caller's registers
XR R15,R15 set return code to 0
BR R14 return to caller
* split(istart,iend) ------recursive---------------------
SPLIT STM R14,R12,12(R13) save all registers
LR R9,R1 save R1
LA R1,72 amount of storage required
GETMAIN RU,LV=(R1) allocate storage for stack
USING STACK,R10 make storage addressable
LR R10,R1 establish stack addressability
LA R11,SAVEXB get the address of my savearea
ST R13,4(R11) save caller's save area pointer
ST R11,8(R13) save my save area pointer
LR R13,R11 set R13 to point to my save area
LR R1,R9 restore R1
LR RSTART,R1 istart=R1
LR REND,R2 iend=R2
IF CR,REND,EQ,RSTART THEN if iend=istart
B RETURN return
ENDIF , end if
BCTR R2,0 iend-1
IF C,R2,EQ,RSTART THEN if iend-istart=1
LR R1,REND iend
SLA R1,2 .
L R2,A-4(R1) a(iend)
LR R1,RSTART istart
SLA R1,2 .
L R3,A-4(R1) a(istart)
IF CR,R2,LT,R3 THEN if a(iend)<a(istart)
LR R1,RSTART istart
SLA R1,2 .
LA R2,A-4(R1) @a(istart)
LR R1,REND iend
SLA R1,2 .
LA R3,A-4(R1) @a(iend)
MVC TEMP,0(R2) temp=a(istart)
MVC 0(4,R2),0(R3) a(istart)=a(iend)
MVC 0(4,R3),TEMP a(iend)=temp
ENDIF , end if
B RETURN return
ENDIF , end if
LR RMIDDL,REND iend
SR RMIDDL,RSTART iend-istart
SRA RMIDDL,1 (iend-istart)/2
AR RMIDDL,RSTART imiddl=istart+(iend-istart)/2
LR R1,RSTART istart
LR R2,RMIDDL imiddl
BAL R14,SPLIT call split(istart,imiddl)
LA R1,1(RMIDDL) imiddl+1
LR R2,REND iend
BAL R14,SPLIT call split(imiddl+1,iend)
LR R1,RSTART istart
LR R2,RMIDDL imiddl
LR R3,REND iend
BAL R14,MERGE call merge(istart,imiddl,iend)
RETURN L R13,SAVEXB+4 restore caller's savearea address
XR R15,R15 set return code to 0
LA R0,72 amount of storage to free
FREEMAIN A=(R10),LV=(R0) free allocated storage
L R14,12(R13) restore caller's return address
LM R2,R12,28(R13) restore registers R2 to R12
BR R14 return to caller
DROP R10 base no longer needed
* merge(jstart,jmiddl,jend) ------------------------------------
MERGE STM R1,R3,JSTART jstart=r1,jmiddl=r2,jend=r3
SR R2,R1 jmiddl-jstart
LA RBS,2(R2) bs=jmiddl-jstart+2
LA RI,1 i=1
LR R3,RBS bs
BCTR R3,0 bs-1
DO WHILE=(CR,RI,LE,R3) do i=0 to bs-1
L R2,JSTART jstart
AR R2,RI jstart+i
SLA R2,2 .
L R2,A-8(R2) a(jstart+i-1)
LR R1,RI i
SLA R1,2 .
ST R2,B-4(R1) b(i)=a(jstart+i-1)
LA RI,1(RI) i=i+1
ENDDO , end do
LA RI,1 i=1
L RJ,JMIDDL j=jmiddl
LA RJ,1(RJ) j=jmiddl+1
L RK,JSTART k=jstart
DO UNTIL=(CR,RI,EQ,RBS,OR, do until i=bs or X
C,RJ,GT,JEND) j>jend
LR R1,RI i
SLA R1,2 .
L R4,B-4(R1) r4=b(i)
LR R1,RJ j
SLA R1,2 .
L R3,A-4(R1) r3=a(j)
LR R9,RK k
SLA R9,2 r9 for a(k)
IF CR,R4,LE,R3 THEN if b(i)<=a(j)
ST R4,A-4(R9) a(k)=b(i)
LA RI,1(RI) i=i+1
ELSE , else
ST R3,A-4(R9) a(k)=a(j)
LA RJ,1(RJ) j=j+1
ENDIF , end if
LA RK,1(RK) k=k+1
ENDDO , end do
DO WHILE=(CR,RI,LT,RBS) do while i<bs
LR R1,RI i
SLA R1,2 .
L R2,B-4(R1) b(i)
LR R1,RK k
SLA R1,2 .
ST R2,A-4(R1) a(k)=b(i)
LA RI,1(RI) i=i+1
LA RK,1(RK) k=k+1
ENDDO , end do
BR R14 return to caller
* ------- ------------------ ------------------------------------
LTORG
SAVEXA DS 18F savearea of main
NN EQU ((B-A)/L'A) number of items
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'
B DS (NN/2+1)F merge sort static storage
TEMP DS F for swap
JSTART DS F jstart
JMIDDL DS F jmiddl
JEND DS F jend
PG DC CL80' ' buffer
XDEC DS CL12 for edit
STACK DSECT dynamic area
SAVEXB DS 18F " savearea of mergsort (72 bytes)
YREGS
RI EQU 6 i
RJ EQU 7 j
RK EQU 8 k
RSTART EQU 6 istart
REND EQU 7 i
RMIDDL EQU 8 i
RPGI EQU 3 pgi
RBS EQU 0 bs
END MAIN

View file

@ -0,0 +1,214 @@
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program mergeSort64.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,11,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 // first element
mov x2,NBELEMENTS // number of élements
bl mergeSort
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
/******************************************************************/
/* merge */
/******************************************************************/
/* r0 contains the address of table */
/* r1 contains first start index
/* r2 contains second start index */
/* r3 contains the last index */
merge:
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
str x8,[sp,-16]!
mov x5,x2 // init index x2->x5
1: // begin loop first section
ldr x6,[x0,x1,lsl 3] // load value first section index r1
ldr x7,[x0,x5,lsl 3] // load value second section index r5
cmp x6,x7
ble 4f // <= -> location first section OK
str x7,[x0,x1,lsl 3] // store value second section in first section
add x8,x5,1
cmp x8,x3 // end second section ?
ble 2f
str x6,[x0,x5,lsl 3]
b 4f // loop
2: // loop insert element part 1 into part 2
sub x4,x8,1
ldr x7,[x0,x8,lsl 3] // load value 2
cmp x6,x7 // value <
bge 3f
str x6,[x0,x4,lsl 3] // store value
b 4f // loop
3:
str x7,[x0,x4,lsl 3] // store value 2
add x8,x8,1
cmp x8,x3 // end second section ?
ble 2b // no loop
sub x8,x8,1
str x6,[x0,x8,lsl 3] // store value 1
4:
add x1,x1,1
cmp x1,x2 // end first section ?
blt 1b
100:
ldr x8,[sp],16 // restaur 1 register
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
/******************************************************************/
/* merge sort */
/******************************************************************/
/* x0 contains the address of table */
/* x1 contains the index of first element */
/* x2 contains the number of element */
mergeSort:
stp x3,lr,[sp,-16]! // save registers
stp x4,x5,[sp,-16]! // save registers
stp x6,x7,[sp,-16]! // save registers
cmp x2,2 // end ?
blt 100f
lsr x4,x2,1 // number of element of each subset
add x5,x4,1
tst x2,#1 // odd ?
csel x4,x5,x4,ne
mov x5,x1 // save first element
mov x6,x2 // save number of element
mov x7,x4 // save number of element of each subset
mov x2,x4
bl mergeSort
mov x1,x7 // restaur number of element of each subset
mov x2,x6 // restaur number of element
sub x2,x2,x1
mov x3,x5 // restaur first element
add x1,x1,x3 // + 1
bl mergeSort // sort first subset
mov x1,x5 // restaur first element
mov x2,x7 // restaur number of element of each subset
add x2,x2,x1
mov x3,x6 // restaur number of element
add x3,x3,x1
sub x3,x3,1 // last index
bl merge
100:
ldp x6,x7,[sp],16 // restaur 2 registers
ldp x4,x5,[sp],16 // restaur 2 registers
ldp x3,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
mov x0,x2
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"

View file

@ -0,0 +1,34 @@
(defun split (xys)
(if (endp (rest xys))
(mv xys nil)
(mv-let (xs ys)
(split (rest (rest xys)))
(mv (cons (first xys) xs)
(cons (second xys) ys)))))
(defun mrg (xs ys)
(declare (xargs :measure (+ (len xs) (len ys))))
(cond ((endp xs) ys)
((endp ys) xs)
((< (first xs) (first ys))
(cons (first xs) (mrg (rest xs) ys)))
(t (cons (first ys) (mrg xs (rest ys))))))
(defthm split-shortens
(implies (consp (rest xs))
(mv-let (ys zs)
(split xs)
(and (< (len ys) (len xs))
(< (len zs) (len xs))))))
(defun msort (xs)
(declare (xargs
:measure (len xs)
:hints (("Goal"
:use ((:instance split-shortens))))))
(if (endp (rest xs))
xs
(mv-let (ys zs)
(split xs)
(mrg (msort ys)
(msort zs)))))

View file

@ -0,0 +1,41 @@
MODE DATA = CHAR;
PROC merge sort = ([]DATA m)[]DATA: (
IF LWB m >= UPB m THEN
m
ELSE
INT middle = ( UPB m + LWB m ) OVER 2;
[]DATA left = merge sort(m[:middle]);
[]DATA right = merge sort(m[middle+1:]);
flex merge(left, right)[AT LWB m]
FI
);
# FLEX version: A demonstration of FLEX for manipulating arrays #
PROC flex merge = ([]DATA in left, in right)[]DATA:(
[UPB in left + UPB in right]DATA result;
FLEX[0]DATA left := in left;
FLEX[0]DATA right := in right;
FOR index TO UPB result DO
# change the direction of this comparison to change the direction of the sort #
IF LWB right > UPB right THEN
result[index:] := left;
stop iteration
ELIF LWB left > UPB left THEN
result[index:] := right;
stop iteration
ELIF left[1] <= right[1] THEN
result[index] := left[1];
left := left[2:]
ELSE
result[index] := right[1];
right := right[2:]
FI
OD;
stop iteration:
result
);
[32]CHAR char array data := "big fjords vex quick waltz nymph";
print((merge sort(char array data), new line));

View file

@ -0,0 +1,38 @@
PROC opt merge sort = ([]REF DATA m)[]REF DATA: (
IF LWB m >= UPB m THEN
m
ELSE
INT middle = ( UPB m + LWB m ) OVER 2;
[]REF DATA left = opt merge sort(m[:middle]);
[]REF DATA right = opt merge sort(m[middle+1:]);
opt merge(left, right)[AT LWB m]
FI
);
PROC opt merge = ([]REF DATA left, right)[]REF DATA:(
[UPB left - LWB left + 1 + UPB right - LWB right + 1]REF DATA result;
INT index left:=LWB left, index right:=LWB right;
FOR index TO UPB result DO
# change the direction of this comparison to change the direction of the sort #
IF index right > UPB right THEN
result[index:] := left[index left:];
stop iteration
ELIF index left > UPB left THEN
result[index:] := right[index right:];
stop iteration
ELIF left[index left] <= right[index right] THEN
result[index] := left[index left]; index left +:= 1
ELSE
result[index] := right[index right]; index right +:= 1
FI
OD;
stop iteration:
result
);
# create an array of pointers to the data being sorted #
[UPB char array data]REF DATA data; FOR i TO UPB char array data DO data[i] := char array data[i] OD;
[]REF CHAR result = opt merge sort(data);
FOR i TO UPB result DO print((result[i])) OD; print(new line)

View file

@ -0,0 +1,196 @@
/* ARM assembly Raspberry PI */
/* program mergeSort.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,11,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
ldr r0,iAdrTableNumber @ address number table
mov r1,#0 @ first element
mov r2,#NBELEMENTS @ number of élements
bl mergeSort
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 1f
ldr r0,iAdrszMessSortNok @ no !! error sort
bl affichageMess
b 100f
1: @ 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
/******************************************************************/
/* merge */
/******************************************************************/
/* r0 contains the address of table */
/* r1 contains first start index
/* r2 contains second start index */
/* r3 contains the last index */
merge:
push {r1-r8,lr} @ save registers
mov r5,r2 @ init index r2->r5
1: @ begin loop first section
ldr r6,[r0,r1,lsl #2] @ load value first section index r1
ldr r7,[r0,r5,lsl #2] @ load value second section index r5
cmp r6,r7
ble 3f @ <= -> location first section OK
str r7,[r0,r1,lsl #2] @ store value second section in first section
add r8,r5,#1
cmp r8,r3 @ end second section ?
strgt r6,[r0,r5,lsl #2]
bgt 3f @ loop
2: @ loop insert element part 1 into part 2
sub r4,r8,#1
ldr r7,[r0,r8,lsl #2] @ load value 2
cmp r6,r7 @ value <
strlt r6,[r0,r4,lsl #2] @ store value
blt 3f
str r7,[r0,r4,lsl #2] @ store value 2
add r8,#1
cmp r8,r3 @ end second section ?
ble 2b @ no loop
sub r8,#1
str r6,[r0,r8,lsl #2] @ store value 1
3:
add r1,#1
cmp r1,r2 @ end first section ?
blt 1b
100:
pop {r1-r8,lr}
bx lr @ return
/******************************************************************/
/* merge sort */
/******************************************************************/
/* r0 contains the address of table */
/* r1 contains the index of first element */
/* r2 contains the number of element */
mergeSort:
push {r3-r7,lr} @ save registers
cmp r2,#2
blt 100f
lsr r4,r2,#1 @ number of element of each subset
tst r2,#1
addne r4,#1
mov r5,r1 @ save first element
mov r6,r2 @ save number of element
mov r7,r4 @ save number of element of each subset
mov r2,r4
bl mergeSort
mov r1,r7 @ restaur number of element of each subset
mov r2,r6 @ restaur number of element
sub r2,r1
mov r3,r5 @ restaur first element
add r1,r3 @ + 1
bl mergeSort @ sort first subset
mov r1,r5 @ restaur first element
mov r2,r7 @ restaur number of element of each subset
add r2,r1
mov r3,r6 @ restaur number of element
add r3,r1
sub r3,#1 @ last index
bl merge
100:
pop {r3-r7,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
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
mov r0,r2
100:
pop {r0-r3,lr}
bx lr
iAdrsZoneConv: .int sZoneConv
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
.include "../affichage.inc"

View file

@ -0,0 +1,105 @@
DEFINE MAX_COUNT="100"
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 Merge(INT ARRAY a INT first,mid,last)
INT ARRAY left(MAX_COUNT),right(MAX_COUNT)
INT leftSize,rightSize,i,j,k
leftSize=mid-first+1
rightSize=last-mid
FOR i=0 TO leftSize-1
DO
left(i)=a(first+i)
OD
FOR i=0 TO rightSize-1
DO
right(i)=a(mid+1+i)
OD
i=0 j=0
k=first
WHILE i<leftSize AND j<rightSize
DO
IF left(i)<=right(j) THEN
a(k)=left(i)
i==+1
ELSE
a(k)=right(j)
j==+1
FI
k==+1
OD
WHILE i<leftSize
DO
a(k)=left(i)
i==+1 k==+1
OD
WHILE j<rightSize
DO
a(k)=right(j)
j==+1 k==+1
OD
RETURN
PROC MergeSort(INT ARRAY a INT size)
INT currSize,first,mid,last
currSize=1
WHILE currSize<size
DO
first=0
WHILE first<size-1
DO
mid=first+currSize-1
IF mid>size-1 THEN
mid=size-1
FI
last=first+2*currSize-1
IF last>size-1 THEN
last=size-1
FI
Merge(a,first,mid,last);
first==+2*currSize
OD
currSize==*2
OD
RETURN
PROC Test(INT ARRAY a INT size)
PrintE("Array before sort:")
PrintArray(a,size)
MergeSort(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

View file

@ -0,0 +1,50 @@
function mergesort(a:Array)
{
//Arrays of length 1 and 0 are always sorted
if(a.length <= 1) return a;
else
{
var middle:uint = a.length/2;
//split the array into two
var left:Array = new Array(middle);
var right:Array = new Array(a.length-middle);
var j:uint = 0, k:uint = 0;
//fill the left array
for(var i:uint = 0; i < middle; i++)
left[j++]=a[i];
//fill the right array
for(i = middle; i< a.length; i++)
right[k++]=a[i];
//sort the arrays
left = mergesort(left);
right = mergesort(right);
//If the last element of the left array is less than or equal to the first
//element of the right array, they are in order and don't need to be merged
if(left[left.length-1] <= right[0])
return left.concat(right);
a = merge(left, right);
return a;
}
}
function merge(left:Array, right:Array)
{
var result:Array = new Array(left.length + right.length);
var j:uint = 0, k:uint = 0, m:uint = 0;
//merge the arrays in order
while(j < left.length && k < right.length)
{
if(left[j] <= right[k])
result[m++] = left[j++];
else
result[m++] = right[k++];
}
//If one of the arrays has remaining entries that haven't been merged, they
//will be greater than the rest of the numbers merged so far, so put them on the
//end of the array.
for(; j < left.length; j++)
result[m++] = left[j];
for(; k < right.length; k++)
result[m++] = right[k];
return result;
}

View file

@ -0,0 +1,9 @@
generic
type Element_Type is private;
type Index_Type is (<>);
type Collection_Type is array(Index_Type range <>) of Element_Type;
with function "<"(Left, Right : Element_Type) return Boolean is <>;
package Mergesort is
function Sort(Item : Collection_Type) return Collection_Type;
end MergeSort;

View file

@ -0,0 +1,62 @@
package body Mergesort is
-----------
-- Merge --
-----------
function Merge(Left, Right : Collection_Type) return Collection_Type is
Result : Collection_Type(Left'First..Right'Last);
Left_Index : Index_Type := Left'First;
Right_Index : Index_Type := Right'First;
Result_Index : Index_Type := Result'First;
begin
while Left_Index <= Left'Last and Right_Index <= Right'Last loop
if Left(Left_Index) <= Right(Right_Index) then
Result(Result_Index) := Left(Left_Index);
Left_Index := Index_Type'Succ(Left_Index); -- increment Left_Index
else
Result(Result_Index) := Right(Right_Index);
Right_Index := Index_Type'Succ(Right_Index); -- increment Right_Index
end if;
Result_Index := Index_Type'Succ(Result_Index); -- increment Result_Index
end loop;
if Left_Index <= Left'Last then
Result(Result_Index..Result'Last) := Left(Left_Index..Left'Last);
end if;
if Right_Index <= Right'Last then
Result(Result_Index..Result'Last) := Right(Right_Index..Right'Last);
end if;
return Result;
end Merge;
----------
-- Sort --
----------
function Sort (Item : Collection_Type) return Collection_Type is
Result : Collection_Type(Item'range);
Middle : Index_Type;
begin
if Item'Length <= 1 then
return Item;
else
Middle := Index_Type'Val((Item'Length / 2) + Index_Type'Pos(Item'First));
declare
Left : Collection_Type(Item'First..Index_Type'Pred(Middle));
Right : Collection_Type(Middle..Item'Last);
begin
for I in Left'range loop
Left(I) := Item(I);
end loop;
for I in Right'range loop
Right(I) := Item(I);
end loop;
Left := Sort(Left);
Right := Sort(Right);
Result := Merge(Left, Right);
end;
return Result;
end if;
end Sort;
end Mergesort;

View file

@ -0,0 +1,19 @@
with Ada.Text_Io; use Ada.Text_Io;
with Mergesort;
procedure Mergesort_Test is
type List_Type is array(Positive range <>) of Integer;
package List_Sort is new Mergesort(Integer, Positive, List_Type);
procedure Print(Item : List_Type) is
begin
for I in Item'range loop
Put(Integer'Image(Item(I)));
end loop;
New_Line;
end Print;
List : List_Type := (1, 5, 2, 7, 3, 9, 4, 6);
begin
Print(List);
Print(List_Sort.Sort(List));
end Mergesort_Test;

View file

@ -0,0 +1,116 @@
(*
In-place, iterative binary merge sort
Merge sort algorithm: John von Neumann, 1945.
Convenience terminology used here:
run: one of two adjacent source-list ranges containing ordered items for merging.
block: range in the destination list to which two runs are merged.
*)
on mergeSort(theList, l, r) -- Sort items l thru r of theList.
set listLength to (count theList)
if (listLength < 2) then return
-- Convert negative and/or transposed range indices.
if (l < 0) then set l to listLength + l + 1
if (r < 0) then set r to listLength + r + 1
if (l > r) then set {l, r} to {r, l}
-- Script object containing the input list and the sort range indices.
script main
property lst : theList
property l : missing value
property r : missing value
end script
set {main's l, main's r} to {l, r}
-- Just swap adjacent items as necessary on the first pass.
-- (Short insertion sorts would be better, to create larger initial runs.)
repeat with j from (l + 1) to r by 2
set i to j - 1
set lv to main's lst's item i
set rv to main's lst's item j
if (lv > rv) then
set main's lst's item i to rv
set main's lst's item j to lv
end if
end repeat
set rangeLength to r - l + 1
if (rangeLength < 3) then return -- That's all if fewer than three items to sort.
-- Script object to alternate with the one above as the source and destination for the
-- merges. Its list need only contain the items from the sort range as ordered so far.
script aux
property lst : main's lst's items l thru r
property l : 1
property r : rangeLength
end script
-- Work out how many merging passes will be needed and set the script objects' initial
-- source and destination roles so that the final pass will merge back to the original list.
set passesToDo to 0
set blockSize to 2
repeat while (blockSize < rangeLength)
set passesToDo to passesToDo + 1
set blockSize to blockSize + blockSize
end repeat
set {srce, dest} to {{main, aux}, {aux, main}}'s item (passesToDo mod 2 + 1)
-- Do the remaining passes, doubling the run and block sizes on each pass.
-- (The end set in each pass will usually be truncated.)
set blockSize to 2
repeat passesToDo times -- Per pass.
set runSize to blockSize
set blockSize to blockSize + blockSize
set k to (dest's l) - 1 -- Destination traversal index.
repeat with leftStart from srce's l to srce's r by blockSize -- Per merge.
set blockEnd to k + blockSize
if (blockEnd comes after dest's r) then set blockEnd to dest's r
set i to leftStart -- Left run traversal index.
set leftEnd to leftStart + runSize - 1
if (leftEnd comes before srce's r) then
set j to leftEnd + 1 -- Right run traversal index.
set rightEnd to leftEnd + runSize
if (rightEnd comes after srce's r) then set rightEnd to srce's r
-- Merge process:
set lv to srce's lst's item i
set rv to srce's lst's item j
repeat with k from (k + 1) to blockEnd
if (lv > rv) then
set dest's lst's item k to rv
if (j = rightEnd) then exit repeat -- Right run used up.
set j to j + 1
set rv to srce's lst's item j
else
set dest's lst's item k to lv
if (i = leftEnd) then -- Left run used up.
set i to j
exit repeat
end if
set i to i + 1
set lv to srce's lst's item i
end if
end repeat
end if
-- Use up the remaining items from the not-yet-exhausted run.
repeat with k from (k + 1) to blockEnd
set dest's lst's item k to srce's lst's item i
set i to i + 1
end repeat
end repeat -- Per merge.
-- Switch source and destination scripts for the next pass.
tell srce
set srce to dest
set dest to it
end tell
end repeat -- Per pass.
return -- nothing
end mergeSort
property sort : mergeSort
-- Demo:
local aList
set aList to {22, 15, 98, 82, 22, 4, 58, 70, 80, 38, 49, 48, 46, 54, 93, 8, 54, 2, 72, 84, 86, 76, 53, 37, 90}
sort(aList, 1, -1) -- Sort items 1 thru -1 of aList.
return aList

View file

@ -0,0 +1 @@
{2, 4, 8, 15, 22, 22, 37, 38, 46, 48, 49, 53, 54, 54, 58, 70, 72, 76, 80, 82, 84, 86, 90, 93, 98}

View file

@ -0,0 +1,61 @@
merge: function [a,b,left,middle,right][
leftLen: middle - left
rightLen: right - middle
l: 0
r: leftLen
loop left..dec middle 'i [
b\[l]: a\[i]
l: l + 1
]
loop middle..dec right 'i [
b\[r]: a\[i]
r: r + 1
]
l: 0
r: leftLen
i: left
while [and? l < leftLen r < leftLen + rightLen][
if? b\[l] < b\[r] [
a\[i]: b\[l]
l: l + 1
]
else [
a\[i]: b\[r]
r: r + 1
]
i: i + 1
]
while [l < leftLen][
a\[i]: b\[l]
l: l + 1
i: i + 1
]
while [r < leftLen + rightLen][
a\[i]: b\[r]
r: r + 1
i: i + 1
]
]
mergeLR: function [a,b,left,right][
if 1 >= right - left -> return ø
mid: (left + right) / 2
mergeLR a b left mid
mergeLR a b mid right
merge a b left mid right
]
mergeSort: function [arr][
result: new arr
b: new array.of:size result 0
mergeLR result b 0 size result
return result
]
print mergeSort [3 1 2 8 5 7 9 4 6]

View file

@ -0,0 +1,17 @@
fun mergesort(m):
if m.lenght <= 1: return m
let middle = floor m.lenght / 2
let left = merge(m[:middle])
let right = merge(m[middle-1:]);
fun merge(left, right):
let result = []
while not (left.isempty or right.isempty):
if left[1] <= right[1]:
result.push! left.shift!()
else:
result.push! right.shift!()
result.push! left.push! right
let arr = [7, 6, 5, 9, 8, 4, 3, 1, 2, 0]
print mergesort arr

View file

@ -0,0 +1,166 @@
(*------------------------------------------------------------------*)
(* Mergesort in ATS2, for linear lists. *)
(*------------------------------------------------------------------*)
#include "share/atspre_staload.hats"
staload UN = "prelude/SATS/unsafe.sats"
#define NIL list_vt_nil ()
#define :: list_vt_cons
(*------------------------------------------------------------------*)
(* Destructive stable merge. *)
extern fun {a : vt@ype}
list_vt_merge {m, n : int}
(lst1 : list_vt (a, m),
lst2 : list_vt (a, n))
:<!wrt> list_vt (a, m + n)
(* Order predicate for list_vt_merge. You have to implement this to
suit your needs. *)
extern fun {a : vt@ype}
list_vt_merge$lt : (&a, &a) -<> bool
(* Destructive stable mergesort. *)
extern fun {a : vt@ype}
list_vt_mergesort {n : int}
(lst : list_vt (a, n))
:<!wrt> list_vt (a, n)
(* Order predicate for list_vt_mergesort. You have to implement this
to suit your needs. *)
extern fun {a : vt@ype}
list_vt_mergesort$lt : (&a, &a) -<> bool
(*------------------------------------------------------------------*)
implement {a}
list_vt_merge {m, n} (lst1, lst2) =
let
macdef lt = list_vt_merge$lt<a>
fun
loop {m, n : nat} .<m + n>.
(lst1 : list_vt (a, m),
lst2 : list_vt (a, n),
lst_merged : &List_vt a? >> list_vt (a, m + n))
:<!wrt> void =
case+ lst1 of
| ~ NIL => lst_merged := lst2
| @ elem1 :: tail1 =>
begin
case+ lst2 of
| ~ NIL =>
let
prval () = fold@ lst1
in
lst_merged := lst1
end
| @ elem2 :: tail2 =>
if ~(elem2 \lt elem1) then
let
val () = lst_merged := lst1
prval () = fold@ lst2
val () = loop (tail1, lst2, tail1)
prval () = fold@ lst_merged
in
end
else
let
val () = lst_merged := lst2
prval () = fold@ lst1
val () = loop (lst1, tail2, tail2)
prval () = fold@ lst_merged
in
end
end
prval () = lemma_list_vt_param lst1 (* Proves 0 <= m. *)
prval () = lemma_list_vt_param lst2 (* Proves 0 <= n. *)
prval () = prop_verify {0 <= m} ()
prval () = prop_verify {0 <= n} ()
var lst_merged : List_vt a?
val () = loop {m, n} (lst1, lst2, lst_merged)
in
lst_merged
end
(*------------------------------------------------------------------*)
implement {a}
list_vt_mergesort {n} lst =
let
implement
list_vt_merge$lt<a> (x, y) =
list_vt_mergesort$lt<a> (x, y)
(* You can make SMALL larger than 1 and write small_sort as a fast
stable sort for small lists. *)
#define SMALL 1
fn
small_sort {m : pos | m <= SMALL}
(lst : list_vt (a, m),
m : int m)
:<!wrt> list_vt (a, m) =
lst
fun
recurs {m : pos} .<m>.
(lst : list_vt (a, m),
m : int m)
:<!wrt> list_vt (a, m) =
if m <= SMALL then
small_sort (lst, m)
else
let
prval () = prop_verify {2 <= m} ()
val i = m / 2
val @(lst1, lst2) = list_vt_split_at<a> (lst, i)
val lst1 = recurs (lst1, i)
val lst2 = recurs (lst2, m - i)
in
list_vt_merge<a> (lst1, lst2)
end
prval () = lemma_list_vt_param lst (* Proves 0 <= n. *)
prval () = prop_verify {0 <= n} ()
in
case+ lst of
| NIL => lst
| _ :: _ => recurs (lst, length lst)
end
(*------------------------------------------------------------------*)
extern fun
list_vt_mergesort_int {n : int}
(lst : list_vt (int, n))
:<!wrt> list_vt (int, n)
implement
list_vt_mergesort_int {n} lst =
let
implement
list_vt_mergesort$lt<int> (x, y) =
x < y
in
list_vt_mergesort<int> {n} lst
end
implement
main0 () =
let
val lst = $list_vt (22, 15, 98, 82, 22, 4, 58, 70, 80, 38, 49,
48, 46, 54, 93, 8, 54, 2, 72, 84, 86, 76,
53, 37, 90)
val () = println! ("before : ", $UN.castvwtp1{List int} lst)
val lst = list_vt_mergesort_int lst
val () = println! ("after : ", $UN.castvwtp1{List int} lst)
in
list_vt_free<int> lst
end
(*------------------------------------------------------------------*)

View file

@ -0,0 +1,223 @@
//--------------------------------------------------------------------
//
// A mergesort for 32-bit signed integers.
//
//--------------------------------------------------------------------
#include "share/atspre_staload.hats"
(*------------------------------------------------------------------*)
#define ENTIER_MAX 2147483647
(* We do not include the most negative two's-complement number. *)
stadef entier (i : int) = ~ENTIER_MAX <= i && i <= ENTIER_MAX
sortdef entier = {i : int | entier i}
typedef entier (i : int) = [entier i] int i
typedef entier = [i : entier] entier i
datatype sorted_entier_list (int, int) =
| sorted_entier_list_nil (0, ENTIER_MAX)
| {n : nat}
{i, j : entier | ~(j < i)}
sorted_entier_list_cons (n + 1, i) of
(entier i, sorted_entier_list (n, j))
typedef sorted_entier_list (n : int) =
[i : entier] sorted_entier_list (n, i)
typedef sorted_entier_list =
[n : int] sorted_entier_list n
infixr ( :: ) :::
#define NIL list_nil ()
#define :: list_cons
#define SNIL sorted_entier_list_nil ()
#define ::: sorted_entier_list_cons
(*------------------------------------------------------------------*)
extern prfn
lemma_sorted_entier_list_param
{n : int}
(lst : sorted_entier_list n)
:<prf> [0 <= n] void
extern fn
sorted_entier_list_length
{n : int}
(lst : sorted_entier_list n)
:<> [0 <= n] int n
extern fn
sorted_entier_list_merge
{m, n : int}
{i, j : entier}
(lst1 : sorted_entier_list (m, i),
lst2 : sorted_entier_list (n, j))
:<> sorted_entier_list (m + n, min (i, j))
extern fn
entier_list_mergesort
{n : int}
(lst : list (entier, n)) (* An ordinary list. *)
:<!wrt> sorted_entier_list n
extern fn
sorted_entier_list2list
{n : int}
(lst : sorted_entier_list n)
:<> list (entier, n)
overload length with sorted_entier_list_length
overload merge with sorted_entier_list_merge
overload mergesort with entier_list_mergesort
overload to_list with sorted_entier_list2list
(*------------------------------------------------------------------*)
primplement
lemma_sorted_entier_list_param {n} lst =
case+ lst of
| SNIL => ()
| _ ::: _ => ()
implement
sorted_entier_list_length {n} lst =
(* This implementation is tail-recursive. *)
let
fun
count {m : nat | m <= n} .<n - m>.
(lst : sorted_entier_list (n - m),
m : int m)
:<> [0 <= n] int n =
case+ lst of
| SNIL => m
| _ ::: tail => count {m + 1} (tail, succ m)
prval () = lemma_sorted_entier_list_param lst
in
count (lst, 0)
end
implement
sorted_entier_list_merge (lst1, lst2) =
(* This implementation is *NOT* tail recursive. It will use O(m+n)
stack space. *)
let
fun
recurs {m, n : nat}
{i, j : entier} .<m + n>.
(lst1 : sorted_entier_list (m, i),
lst2 : sorted_entier_list (n, j))
:<> sorted_entier_list (m + n, min (i, j)) =
case+ lst1 of
| SNIL => lst2
| i ::: tail1 =>
begin
case+ lst2 of
| SNIL => lst1
| j ::: tail2 =>
if ~(j < i) then
i ::: recurs (tail1, lst2)
else
j ::: recurs (lst1, tail2)
end
prval () = lemma_sorted_entier_list_param lst1
prval () = lemma_sorted_entier_list_param lst2
in
recurs (lst1, lst2)
end
implement
entier_list_mergesort lst =
let
fun
recurs {m : nat} .<m>.
(lst : list (entier, m),
m : int m)
:<!wrt> sorted_entier_list m =
if m = 1 then
let
val+ head :: NIL = lst
in
head ::: SNIL
end
else if m = 0 then
SNIL
else
let
val m_left = m \g1int_ndiv 2
val m_right = m - m_left
val @(left, right) = list_split_at (lst, m_left)
val left = recurs (list_vt2t left, m_left)
and right = recurs (right, m_right)
in
left \merge right
end
prval () = lemma_list_param lst
in
recurs (lst, length lst)
end
implement
sorted_entier_list2list lst =
(* This implementation is *NOT* tail recursive. It will use O(n)
stack space. *)
let
fun
recurs {n : nat} .<n>.
(lst : sorted_entier_list n)
:<> list (entier, n) =
case+ lst of
| SNIL => NIL
| head ::: tail => head :: recurs tail
prval () = lemma_sorted_entier_list_param lst
in
recurs lst
end
(*------------------------------------------------------------------*)
fn
print_Int_list
{n : int}
(lst : list (Int, n))
: void =
let
fun
loop {n : nat} .<n>.
(lst : list (Int, n))
: void =
case+ lst of
| NIL => ()
| head :: tail =>
begin
print! (" ");
print! (head);
loop tail
end
prval () = lemma_list_param lst
in
loop lst
end
implement
main0 () =
let
val example_list =
$list (22, 15, 98, 82, 22, 4, 58, 70, 80, 38, 49, 48, 46, 54,
93, 8, 54, 2, 72, 84, 86, 76, 53, 37, 90)
val sorted_list = mergesort example_list
in
print! ("unsorted ");
print_Int_list example_list;
println! ();
print! ("sorted ");
print_Int_list (to_list sorted_list);
println! ()
end
(*------------------------------------------------------------------*)

View file

@ -0,0 +1,63 @@
#NoEnv
Test := []
Loop 100 {
Random n, 0, 999
Test.Insert(n)
}
Result := MergeSort(Test)
Loop % Result.MaxIndex() {
MsgBox, 1, , % Result[A_Index]
IfMsgBox Cancel
Break
}
Return
/*
Function MergeSort
Sorts an array by first recursively splitting it down to its
individual elements and then merging those elements in their
correct order.
Parameters
Array The array to be sorted
Returns
The sorted array
*/
MergeSort(Array)
{
; Return single element arrays
If (! Array.HasKey(2))
Return Array
; Split array into Left and Right halfs
Left := [], Right := [], Middle := Array.MaxIndex() // 2
Loop % Middle
Right.Insert(Array.Remove(Middle-- + 1)), Left.Insert(Array.Remove(1))
If (Array.MaxIndex())
Right.Insert(Array.Remove(1))
Left := MergeSort(Left), Right := MergeSort(Right)
; If all the Right values are greater than all the
; Left values, just append Right at the end of Left.
If (Left[Left.MaxIndex()] <= Right[1]) {
Loop % Right.MaxIndex()
Left.Insert(Right.Remove(1))
Return Left
}
; Loop until one of the arrays is empty
While(Left.MaxIndex() and Right.MaxIndex())
Left[1] <= Right[1] ? Array.Insert(Left.Remove(1))
: Array.Insert(Right.Remove(1))
Loop % Left.MaxIndex()
Array.Insert(Left.Remove(1))
Loop % Right.MaxIndex()
Array.Insert(Right.Remove(1))
Return Array
}

View file

@ -0,0 +1,37 @@
MsgBox % MSort("")
MsgBox % MSort("xxx")
MsgBox % MSort("3,2,1")
MsgBox % MSort("dog,000000,cat,pile,abcde,1,zz,xx,z")
MSort(x) { ; Merge-sort of a comma separated list
If (2 > L:=Len(x))
Return x ; empty or single item lists are sorted
StringGetPos p, x, `,, % "L" L//2 ; Find middle comma
Return Merge(MSort(SubStr(x,1,p)), MSort(SubStr(x,p+2))) ; Split, Sort, Merge
}
Len(list) {
StringReplace t, list,`,,,UseErrorLevel ; #commas -> ErrorLevel
Return list="" ? 0 : ErrorLevel+1
}
Item(list,ByRef p) { ; item at position p, p <- next position
Return (p := InStr(list,",",0,i:=p+1)) ? SubStr(list,i,p-i) : SubStr(list,i)
}
Merge(list0,list1) { ; Merge 2 sorted lists
IfEqual list0,, Return list1
IfEqual list1,, Return list0
i0 := Item(list0,p0:=0)
i1 := Item(list1,p1:=0)
Loop {
i := i0>i1
list .= "," i%i% ; output smaller
If (p%i%)
i%i% := Item(list%i%,p%i%) ; get next item from processed list
Else {
i ^= 1 ; list is exhausted: attach rest of other
Return SubStr(list "," i%i% (p%i% ? "," SubStr(list%i%,p%i%+1) : ""), 2)
}
}
}

View file

@ -0,0 +1,56 @@
DEFPROC_MergeSort(Start%,End%)
REM *****************************************************************
REM This procedure Merge Sorts the chunk of data% bounded by
REM Start% & End%.
REM *****************************************************************
LOCAL Middle%
IF End%=Start% ENDPROC
IF End%-Start%=1 THEN
IF data%(End%)<data%(Start%) THEN
SWAP data%(Start%),data%(End%)
ENDIF
ENDPROC
ENDIF
Middle%=Start%+(End%-Start%)/2
PROC_MergeSort(Start%,Middle%)
PROC_MergeSort(Middle%+1,End%)
PROC_Merge(Start%,Middle%,End%)
ENDPROC
:
DEF PROC_Merge(Start%,Middle%,End%)
LOCAL fh_size%
fh_size% = Middle%-Start%+1
FOR I%=0 TO fh_size%-1
fh%(I%)=data%(Start%+I%)
NEXT I%
I%=0
J%=Middle%+1
K%=Start%
REPEAT
IF fh%(I%) <= data%(J%) THEN
data%(K%)=fh%(I%)
I%+=1
K%+=1
ELSE
data%(K%)=data%(J%)
J%+=1
K%+=1
ENDIF
UNTIL I%=fh_size% OR J%>End%
WHILE I% < fh_size%
data%(K%)=fh%(I%)
I%+=1
K%+=1
ENDWHILE
ENDPROC

View file

@ -0,0 +1,15 @@
REM Example of merge sort usage.
Size%=1000
S1%=Size%/2
DIM data%(Size%)
DIM fh%(S1%)
FOR I%=1 TO Size%
data%(I%)=RND(100000)
NEXT
PROC_MergeSort(1,Size%)
END

View file

@ -0,0 +1,38 @@
get "libhdr"
let mergesort(A, n) be if n >= 2
$( let m = n / 2
mergesort(A, m)
mergesort(A+m, n-m)
merge(A, n, m)
$)
and merge(A, n, m) be
$( let i, j = 0, m
let x = getvec(n)
for k=0 to n-1
x!k := A!valof
test j~=n & (i=m | A!j < A!i)
$( j := j + 1
resultis j - 1
$)
else
$( i := i + 1
resultis i - 1
$)
for i=0 to n-1 do a!i := x!i
freevec(x)
$)
let write(s, A, len) be
$( writes(s)
for i=0 to len-1 do writed(A!i, 4)
wrch('*N')
$)
let start() be
$( let array = table 4,65,2,-31,0,99,2,83,782,1
let length = 10
write("Before: ", array, length)
mergesort(array, length)
write("After: ", array, length)
$)

View file

@ -0,0 +1,21 @@
#include <iterator>
#include <algorithm> // for std::inplace_merge
#include <functional> // for std::less
template<typename RandomAccessIterator, typename Order>
void mergesort(RandomAccessIterator first, RandomAccessIterator last, Order order)
{
if (last - first > 1)
{
RandomAccessIterator middle = first + (last - first) / 2;
mergesort(first, middle, order);
mergesort(middle, last, order);
std::inplace_merge(first, middle, last, order);
}
}
template<typename RandomAccessIterator>
void mergesort(RandomAccessIterator first, RandomAccessIterator last)
{
mergesort(first, last, std::less<typename std::iterator_traits<RandomAccessIterator>::value_type>());
}

View file

@ -0,0 +1,125 @@
namespace RosettaCode {
using System;
public class MergeSort<T> where T : IComparable {
#region Constants
public const UInt32 INSERTION_LIMIT_DEFAULT = 12;
public const Int32 MERGES_DEFAULT = 6;
#endregion
#region Properties
public UInt32 InsertionLimit { get; }
protected UInt32[] Positions { get; set; }
private Int32 merges;
public Int32 Merges {
get { return merges; }
set {
// A minimum of 2 merges are required
if (value > 1)
merges = value;
else
throw new ArgumentOutOfRangeException($"value = {value} must be greater than one", nameof(Merges));
if (Positions == null || Positions.Length != merges)
Positions = new UInt32[merges];
}
}
#endregion
#region Constructors
public MergeSort(UInt32 insertionLimit, Int32 merges) {
InsertionLimit = insertionLimit;
Merges = merges;
}
public MergeSort()
: this(INSERTION_LIMIT_DEFAULT, MERGES_DEFAULT) {
}
#endregion
#region Sort Methods
public void Sort(T[] entries) {
// Allocate merge buffer
var entries2 = new T[entries.Length];
Sort(entries, entries2, 0, entries.Length - 1);
}
// Top-Down K-way Merge Sort
public void Sort(T[] entries1, T[] entries2, Int32 first, Int32 last) {
var length = last + 1 - first;
if (length < 2) return;
if (length < Merges || length < InsertionLimit) {
InsertionSort<T>.Sort(entries1, first, last);
return;
}
var left = first;
var size = ceiling(length, Merges);
for (var remaining = length; remaining > 0; remaining -= size, left += size) {
var right = left + Math.Min(remaining, size) - 1;
Sort(entries1, entries2, left, right);
}
Merge(entries1, entries2, first, last);
Array.Copy(entries2, first, entries1, first, length);
}
#endregion
#region Merge Methods
public void Merge(T[] entries1, T[] entries2, Int32 first, Int32 last) {
Array.Clear(Positions, 0, Merges);
// This implementation has a quadratic time dependency on the number of merges
for (var index = first; index <= last; index++)
entries2[index] = remove(entries1, first, last);
}
private T remove(T[] entries, Int32 first, Int32 last) {
T entry = default;
Int32? found = default;
var length = last + 1 - first;
var index = 0;
var left = first;
var size = ceiling(length, Merges);
for (var remaining = length; remaining > 0; remaining -= size, left += size, index++) {
var position = Positions[index];
if (position < Math.Min(remaining, size)) {
var next = entries[left + position];
if (!found.HasValue || entry.CompareTo(next) > 0) {
found = index;
entry = next;
}
}
}
// Remove entry
Positions[found.Value]++;
return entry;
}
#endregion
#region Math Methods
private static Int32 ceiling(Int32 numerator, Int32 denominator) {
return (numerator + denominator - 1) / denominator;
}
#endregion
}
#region Insertion Sort
static class InsertionSort<T> where T : IComparable {
public static void Sort(T[] entries, Int32 first, Int32 last) {
for (var next = first + 1; next <= last; next++)
insert(entries, first, next);
}
/// <summary>Bubble next entry up to its sorted location, assuming entries[first:next - 1] are already sorted.</summary>
private static void insert(T[] entries, Int32 first, Int32 next) {
var entry = entries[next];
while (next > first && entries[next - 1].CompareTo(entry) > 0)
entries[next] = entries[--next];
entries[next] = entry;
}
}
#endregion
}

View file

@ -0,0 +1,11 @@
using Sort;
using System;
class Program {
static void Main(String[] args) {
var entries = new Int32[] { 7, 5, 2, 6, 1, 4, 2, 6, 3 };
var sorter = new MergeSort<Int32>();
sorter.Sort(entries);
Console.WriteLine(String.Join(" ", entries));
}
}

View file

@ -0,0 +1,38 @@
#include <stdio.h>
#include <stdlib.h>
void merge (int *a, int n, int m) {
int i, j, k;
int *x = malloc(n * sizeof (int));
for (i = 0, j = m, k = 0; k < n; k++) {
x[k] = j == n ? a[i++]
: i == m ? a[j++]
: a[j] < a[i] ? a[j++]
: a[i++];
}
for (i = 0; i < n; i++) {
a[i] = x[i];
}
free(x);
}
void merge_sort (int *a, int n) {
if (n < 2)
return;
int m = n / 2;
merge_sort(a, m);
merge_sort(a + m, n - m);
merge(a, n, m);
}
int main () {
int a[] = {4, 65, 2, -31, 0, 99, 2, 83, 782, 1};
int n = sizeof a / sizeof a[0];
int i;
for (i = 0; i < n; i++)
printf("%d%s", a[i], i == n - 1 ? "\n" : " ");
merge_sort(a, n);
for (i = 0; i < n; i++)
printf("%d%s", a[i], i == n - 1 ? "\n" : " ");
return 0;
}

View file

@ -0,0 +1,59 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* x and y are sorted, copy nx+ny sorted values to r */
void merge(int nx, int*x, int ny, int*y, int*r) {
int i= 0, j= 0, k= 0;
while (i<nx && j<ny) {
int a= x[i], b= y[j];
if (a<b) {
r[k++]= a;
i++;
} else {
r[k++]= b;
j++;
}
}
if (i<nx) {
memcpy(r+k, i+x, (nx-i)*sizeof (int));
} else if (j<ny) {
memcpy(r+k, j+y, (ny-j)*sizeof (int));
}
}
void mergesort(int ny, int *y) {
int stride= 1, mid, *r= y, *t, *x= malloc(ny*sizeof (int));
while (stride < ny) {
stride= 2*(mid= stride);
for (int i= 0; i<ny; i+= stride) {
int lim= mid;
if (i+stride >= ny) {
if (i+mid >= ny) {
memcpy(i+x, i+y, (ny-i)*sizeof (int));
continue;
}
lim= ny-(i+mid);
}
merge(mid, i+y, lim, i+mid+y, i+x);
}
t= x; x= y; y=t;
}
if (y!=r) {
memcpy(r, y, ny*sizeof(int));
x= y;
}
free(x);
}
int main () {
int a[] = {4, 65, 2, -31, 0, 99, 2, 83, 782, 1};
int n = sizeof a / sizeof a[0];
int i;
for (i = 0; i < n; i++)
printf("%d%s", a[i], i == n - 1 ? "\n" : " ");
mergesort(n, a);
for (i = 0; i < n; i++)
printf("%d%s", a[i], i == n - 1 ? "\n" : " ");
return 0;
}

View file

@ -0,0 +1,293 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. MERGESORT.
AUTHOR. DAVE STRATFORD.
DATE-WRITTEN. APRIL 2010.
INSTALLATION. HEXAGON SYSTEMS LIMITED.
******************************************************************
* MERGE SORT *
* The Merge sort uses a completely different paradigm, one of *
* divide and conquer, to many of the other sorts. The data set *
* is split into smaller sub sets upon which are sorted and then *
* merged together to form the final sorted data set. *
* This version uses the recursive method. Split the data set in *
* half and perform a merge sort on each half. This in turn splits*
* each half again and again until each set is just one or 2 items*
* long. A set of one item is already sorted so is ignored, a set *
* of two is compared and swapped as necessary. The smaller data *
* sets are then repeatedly merged together to eventually form the*
* full, sorted, set. *
* Since cobol cannot do recursion this module only simulates it *
* so is not as fast as a normal recursive version would be. *
* Scales very well to larger data sets, its relative complexity *
* means it is not suited to sorting smaller data sets: use an *
* Insertion sort instead as the Merge sort is a stable sort. *
******************************************************************
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. ICL VME.
OBJECT-COMPUTER. ICL VME.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FA-INPUT-FILE ASSIGN FL01.
SELECT FB-OUTPUT-FILE ASSIGN FL02.
DATA DIVISION.
FILE SECTION.
FD FA-INPUT-FILE.
01 FA-INPUT-REC.
03 FA-DATA PIC 9(6).
FD FB-OUTPUT-FILE.
01 FB-OUTPUT-REC PIC 9(6).
WORKING-STORAGE SECTION.
01 WA-IDENTITY.
03 WA-PROGNAME PIC X(10) VALUE "MERGESORT".
03 WA-VERSION PIC X(6) VALUE "000001".
01 WB-TABLE.
03 WB-ENTRY PIC 9(8) COMP SYNC OCCURS 100000
INDEXED BY WB-IX-1
WB-IX-2.
01 WC-VARS.
03 WC-SIZE PIC S9(8) COMP SYNC.
03 WC-TEMP PIC S9(8) COMP SYNC.
03 WC-START PIC S9(8) COMP SYNC.
03 WC-MIDDLE PIC S9(8) COMP SYNC.
03 WC-END PIC S9(8) COMP SYNC.
01 WD-FIRST-HALF.
03 WD-FH-MAX PIC S9(8) COMP SYNC.
03 WD-ENTRY PIC 9(8) COMP SYNC OCCURS 50000
INDEXED BY WD-IX.
01 WF-CONDITION-FLAGS.
03 WF-EOF-FLAG PIC X.
88 END-OF-FILE VALUE "Y".
03 WF-EMPTY-FILE-FLAG PIC X.
88 EMPTY-FILE VALUE "Y".
01 WS-STACK.
* This stack is big enough to sort a list of 1million items.
03 WS-STACK-ENTRY OCCURS 20 INDEXED BY WS-STACK-TOP.
05 WS-START PIC S9(8) COMP SYNC.
05 WS-MIDDLE PIC S9(8) COMP SYNC.
05 WS-END PIC S9(8) COMP SYNC.
05 WS-FS-FLAG PIC X.
88 FIRST-HALF VALUE "F".
88 SECOND-HALF VALUE "S".
88 WS-ALL VALUE "A".
05 WS-IO-FLAG PIC X.
88 WS-IN VALUE "I".
88 WS-OUT VALUE "O".
PROCEDURE DIVISION.
A-MAIN SECTION.
A-000.
PERFORM B-INITIALISE.
IF NOT EMPTY-FILE
PERFORM C-PROCESS.
PERFORM D-FINISH.
A-999.
STOP RUN.
B-INITIALISE SECTION.
B-000.
DISPLAY "*** " WA-PROGNAME " VERSION "
WA-VERSION " STARTING ***".
MOVE ALL "N" TO WF-CONDITION-FLAGS.
OPEN INPUT FA-INPUT-FILE.
SET WB-IX-1 TO 0.
READ FA-INPUT-FILE AT END MOVE "Y" TO WF-EOF-FLAG
WF-EMPTY-FILE-FLAG.
PERFORM BA-READ-INPUT UNTIL END-OF-FILE.
CLOSE FA-INPUT-FILE.
SET WC-SIZE TO WB-IX-1.
B-999.
EXIT.
BA-READ-INPUT SECTION.
BA-000.
SET WB-IX-1 UP BY 1.
MOVE FA-DATA TO WB-ENTRY(WB-IX-1).
READ FA-INPUT-FILE AT END MOVE "Y" TO WF-EOF-FLAG.
BA-999.
EXIT.
C-PROCESS SECTION.
C-000.
DISPLAY "SORT STARTING".
MOVE 1 TO WS-START(1).
MOVE WC-SIZE TO WS-END(1).
MOVE "F" TO WS-FS-FLAG(1).
MOVE "I" TO WS-IO-FLAG(1).
SET WS-STACK-TOP TO 2.
PERFORM E-MERGE-SORT UNTIL WS-OUT(1).
DISPLAY "SORT FINISHED".
C-999.
EXIT.
D-FINISH SECTION.
D-000.
OPEN OUTPUT FB-OUTPUT-FILE.
SET WB-IX-1 TO 1.
PERFORM DA-WRITE-OUTPUT UNTIL WB-IX-1 > WC-SIZE.
CLOSE FB-OUTPUT-FILE.
DISPLAY "*** " WA-PROGNAME " FINISHED ***".
D-999.
EXIT.
DA-WRITE-OUTPUT SECTION.
DA-000.
WRITE FB-OUTPUT-REC FROM WB-ENTRY(WB-IX-1).
SET WB-IX-1 UP BY 1.
DA-999.
EXIT.
******************************************************************
E-MERGE-SORT SECTION.
*===================== *
* This section controls the simulated recursion. *
******************************************************************
E-000.
IF WS-OUT(WS-STACK-TOP - 1)
GO TO E-010.
MOVE WS-START(WS-STACK-TOP - 1) TO WC-START.
MOVE WS-END(WS-STACK-TOP - 1) TO WC-END.
* First check size of part we are dealing with.
IF WC-END - WC-START = 0
* Only 1 number in range, so simply set for output, and move on
MOVE "O" TO WS-IO-FLAG(WS-STACK-TOP - 1)
GO TO E-010.
IF WC-END - WC-START = 1
* 2 numbers, so compare and swap as necessary. Set for output
MOVE "O" TO WS-IO-FLAG(WS-STACK-TOP - 1)
IF WB-ENTRY(WC-START) > WB-ENTRY(WC-END)
MOVE WB-ENTRY(WC-START) TO WC-TEMP
MOVE WB-ENTRY(WC-END) TO WB-ENTRY(WC-START)
MOVE WC-TEMP TO WB-ENTRY(WC-END)
GO TO E-010
ELSE
GO TO E-010.
* More than 2, so split and carry on down
COMPUTE WC-MIDDLE = ( WC-START + WC-END ) / 2.
MOVE WC-START TO WS-START(WS-STACK-TOP).
MOVE WC-MIDDLE TO WS-END(WS-STACK-TOP).
MOVE "F" TO WS-FS-FLAG(WS-STACK-TOP).
MOVE "I" TO WS-IO-FLAG(WS-STACK-TOP).
SET WS-STACK-TOP UP BY 1.
GO TO E-999.
E-010.
SET WS-STACK-TOP DOWN BY 1.
IF SECOND-HALF(WS-STACK-TOP)
GO TO E-020.
MOVE WS-START(WS-STACK-TOP - 1) TO WC-START.
MOVE WS-END(WS-STACK-TOP - 1) TO WC-END.
COMPUTE WC-MIDDLE = ( WC-START + WC-END ) / 2 + 1.
MOVE WC-MIDDLE TO WS-START(WS-STACK-TOP).
MOVE WC-END TO WS-END(WS-STACK-TOP).
MOVE "S" TO WS-FS-FLAG(WS-STACK-TOP).
MOVE "I" TO WS-IO-FLAG(WS-STACK-TOP).
SET WS-STACK-TOP UP BY 1.
GO TO E-999.
E-020.
MOVE WS-START(WS-STACK-TOP - 1) TO WC-START.
MOVE WS-END(WS-STACK-TOP - 1) TO WC-END.
COMPUTE WC-MIDDLE = ( WC-START + WC-END ) / 2.
PERFORM H-PROCESS-MERGE.
MOVE "O" TO WS-IO-FLAG(WS-STACK-TOP - 1).
E-999.
EXIT.
******************************************************************
H-PROCESS-MERGE SECTION.
*======================== *
* This section identifies which data is to be merged, and then *
* merges the two data streams into a single larger data stream. *
******************************************************************
H-000.
INITIALISE WD-FIRST-HALF.
COMPUTE WD-FH-MAX = WC-MIDDLE - WC-START + 1.
SET WD-IX TO 1.
PERFORM HA-COPY-OUT VARYING WB-IX-1 FROM WC-START BY 1
UNTIL WB-IX-1 > WC-MIDDLE.
SET WB-IX-1 TO WC-START.
SET WB-IX-2 TO WC-MIDDLE.
SET WB-IX-2 UP BY 1.
SET WD-IX TO 1.
PERFORM HB-MERGE UNTIL WD-IX > WD-FH-MAX OR WB-IX-2 > WC-END.
PERFORM HC-COPY-BACK UNTIL WD-IX > WD-FH-MAX.
H-999.
EXIT.
HA-COPY-OUT SECTION.
HA-000.
MOVE WB-ENTRY(WB-IX-1) TO WD-ENTRY(WD-IX).
SET WD-IX UP BY 1.
HA-999.
EXIT.
HB-MERGE SECTION.
HB-000.
IF WB-ENTRY(WB-IX-2) < WD-ENTRY(WD-IX)
MOVE WB-ENTRY(WB-IX-2) TO WB-ENTRY(WB-IX-1)
SET WB-IX-2 UP BY 1
ELSE
MOVE WD-ENTRY(WD-IX) TO WB-ENTRY(WB-IX-1)
SET WD-IX UP BY 1.
SET WB-IX-1 UP BY 1.
HB-999.
EXIT.
HC-COPY-BACK SECTION.
HC-000.
MOVE WD-ENTRY(WD-IX) TO WB-ENTRY(WB-IX-1).
SET WD-IX UP BY 1.
SET WB-IX-1 UP BY 1.
HC-999.
EXIT.

View file

@ -0,0 +1,81 @@
100 REM Sorting algorithms/Merge sort
110 CLS
120 LET N = 10
130 LET C = 0
140 OPTION BASE 1
150 DIM A(10)
160 DIM B(10)
170 RANDOMIZE TIMER
180 GOSUB 810
190 REM Print the random array
200 PRINT "unsort ";
210 GOSUB 860
220 REM Sort the array
230 GOSUB 300
240 PRINT " sort ";
250 REM Print the sorted array
260 GOSUB 860
270 PRINT "Number of iterations: ";C
290 END
300 REM Merge sort the list A of length N
310 REM Using the array B for temporary storage
320 REM
330 REM === Split phase ===
340 REM C counts the number of split/merge iterations
350 LET C = C+1
360 LET X = 1
370 LET Y = 1
380 LET Z = N
390 GOTO 410
400 IF A(X) < A(X-1) THEN GOTO 470
410 LET B(Y) = A(X)
420 LET Y = Y+1
430 LET X = X+1
440 IF Z < Y THEN GOTO 500
450 GOTO 400
460 IF A(X) < A(X-1) THEN GOTO 410
470 LET B(Z) = A(X)
480 LET Z = Z-1
490 LET X = X+1
500 IF Z < Y THEN GOTO 530
510 GOTO 460
520 REM
530 REM === Merge Phase ===
540 REM Q means "we're done" (or "quit")
550 REM Q is 1 until we know that this is _not_ the last iteration
560 LET Q = 1
570 LET X = 1
580 LET Y = 1
590 LET Z = N
600 REM First select the smaller item
610 IF B(Y) < B(Z) THEN GOTO 710 ELSE GOTO 750
620 REM Check if the loop is done
630 IF Z < Y THEN GOTO 790
640 REM If both items are smaller then start over with the smallest
650 IF B(Y) >= A(X-1) OR B(Z) >= A(X-1) THEN GOTO 680
660 LET Q = 0
670 GOTO 600
680 REM Pick the smallest item that represents an increase
690 IF B(Z) < B(Y) AND B(Z) >= A(X-1) THEN GOTO 750
700 IF B(Z) > B(Y) AND B(Y) < A(X-1) THEN GOTO 750
710 LET A(X) = B(Y)
720 LET Y = Y+1
730 LET X = X+1
740 GOTO 620
750 LET A(X) = B(Z)
760 LET Z = Z-1
770 LET X = X+1
780 GOTO 620
790 IF Q = 0 THEN GOTO 330
800 RETURN
810 REM Create a random list of N integers
820 FOR I = 1 TO N
830 LET A(I) = FLOOR(RND(100))
840 NEXT I
850 RETURN
860 REM PRINT the list A
870 FOR I = 1 TO N
880 PRINT A(I);" ";
890 NEXT I
900 PRINT
910 RETURN

View file

@ -0,0 +1,13 @@
(defn merge [left right]
(cond (nil? left) right
(nil? right) left
:else (let [[l & *left] left
[r & *right] right]
(if (<= l r) (cons l (merge *left right))
(cons r (merge left *right))))))
(defn merge-sort [list]
(if (< (count list) 2)
list
(let [[left right] (split-at (/ (count list) 2) list)]
(merge (merge-sort left) (merge-sort right)))))

View file

@ -0,0 +1,25 @@
# This is a simple version of mergesort that returns brand-new arrays.
# A more sophisticated version would do more in-place optimizations.
merge_sort = (arr) ->
if arr.length <= 1
return (elem for elem in arr)
m = Math.floor(arr.length / 2)
arr1 = merge_sort(arr.slice 0, m)
arr2 = merge_sort(arr.slice m)
result = []
p1 = p2 = 0
while true
if p1 >= arr1.length
if p2 >= arr2.length
return result
result.push arr2[p2]
p2 += 1
else if p2 >= arr2.length or arr1[p1] < arr2[p2]
result.push arr1[p1]
p1 += 1
else
result.push arr2[p2]
p2 += 1
do ->
console.log merge_sort [2,4,6,8,1,3,5,7,9,10,11,0,13,12]

View file

@ -0,0 +1,7 @@
(defun merge-sort (result-type sequence predicate)
(let ((split (floor (length sequence) 2)))
(if (zerop split)
(copy-seq sequence)
(merge result-type (merge-sort result-type (subseq sequence 0 split) predicate)
(merge-sort result-type (subseq sequence split) predicate)
predicate))))

View file

@ -0,0 +1,18 @@
def merge_sort(a : Array(Int32)) : Array(Int32)
return a if a.size <= 1
m = a.size // 2
lt = merge_sort(a[0 ... m])
rt = merge_sort(a[m .. -1])
return merge(lt, rt)
end
def merge(lt : Array(Int32), rt : Array(Int32)) : Array(Int32)
result = Array(Int32).new
until lt.empty? || rt.empty?
result << (lt.first < rt.first ? lt.shift : rt.shift)
end
return result + lt + rt
end
a = [7, 6, 5, 9, 8, 4, 3, 1, 2, 0]
puts merge_sort(a) # => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

View file

@ -0,0 +1,30 @@
-- merge sort: sorting two lists by merging the sorted first
-- and second half of the list
sort :: ([a] -> [a] -> [a] -> Success) -> [a] -> [a] -> Success
sort merge xs ys =
if length xs < 2 then ys =:= xs
else sort merge (firsthalf xs) us
& sort merge (secondhalf xs) vs
& merge us vs ys
where us,vs free
intMerge :: [Int] -> [Int] -> [Int] -> Success
intMerge [] ys zs = zs =:= ys
intMerge (x:xs) [] zs = zs =:= x:xs
intMerge (x:xs) (y:ys) zs =
if (x > y) then intMerge (x:xs) ys us & zs =:= y:us
else intMerge xs (y:ys) vs & zs =:= x:vs
where us,vs free
firsthalf xs = take (length xs `div` 2) xs
secondhalf xs = drop (length xs `div` 2) xs
goal1 xs = sort intMerge [3,1,2] xs
goal2 xs = sort intMerge [3,1,2,5,4,8] xs
goal3 xs = sort intMerge [3,1,2,5,4,8,6,7,2,9,1,4,3] xs

View file

@ -0,0 +1,12 @@
import std.stdio, std.algorithm, std.array, std.range;
T[] mergeSorted(T)(in T[] D) /*pure nothrow @safe*/ {
if (D.length < 2)
return D.dup;
return [D[0 .. $ / 2].mergeSorted, D[$ / 2 .. $].mergeSorted]
.nWayUnion.array;
}
void main() {
[3, 4, 2, 5, 1, 6].mergeSorted.writeln;
}

View file

@ -0,0 +1,19 @@
import std.stdio, std.algorithm, core.stdc.stdlib, std.exception,
std.range;
void mergeSort(T)(T[] data) if (hasSwappableElements!(typeof(data))) {
immutable L = data.length;
if (L < 2) return;
T* ptr = cast(T*)alloca(L * T.sizeof);
enforce(ptr != null);
ptr[0 .. L] = data[];
mergeSort(ptr[0 .. L/2]);
mergeSort(ptr[L/2 .. L]);
[ptr[0 .. L/2], ptr[L/2 .. L]].nWayUnion().copy(data);
}
void main() {
auto a = [3, 4, 2, 5, 1, 6];
a.mergeSort();
writeln(a);
}

View file

@ -0,0 +1,118 @@
void main() {
MergeSortInDart sampleSort = MergeSortInDart();
List<int> theResultingList = sampleSort.sortTheList([54, 89, 125, 47899, 32, 61, 42, 895647, 215, 345, 6, 21, 2, 78]);
print('Here\'s the sorted list: ${theResultingList}');
}
/////////////////////////////////////
class MergeSortInDart {
List<int> sortedList;
// In Dart we often put helper functions at the bottom.
// You could put them anywhere, we just like it this way
// for organizational purposes. It's nice to be able to
// read them in the order they're called.
// Start here
List<int> sortTheList(List<int> sortThis){
// My parameters are listed vertically for readability. Dart
// doesn't care how you list them, vertically or horizontally.
sortedList = mSort(
sortThis,
sortThis.sublist(0, sortThis.length),
sortThis.length,
);
return sortThis;
}
mSort(
List<int> sortThisList,
List<int> tempList,
int thisListLength) {
if (thisListLength == 1) {
return;
}
// In Dart using ~/ is more efficient than using .floor()
int middle = (thisListLength ~/ 2);
// If you use something in a try/on/catch/finally block then
// be sure to declare it outside the block (for scope)
List<int> tempLeftList;
// This was used for troubleshooting. It was left here to show
// how a basic block try/on can be better than a debugPrint since
// it won't print unless there's a problem.
try {
tempLeftList = tempList.sublist(0, middle);
} on RangeError {
print(
'tempLeftList length = ${tempList.length}, thisListLength '
'was supposedly $thisListLength and Middle was $middle');
}
// If you see "myList.getRange(x,y)" that's a sign the code is
// from Dart 1 and needs to be updated. It's "myList.sublist" in Dart 2
List<int> tempRightList = tempList.sublist(middle);
// Left side.
mSort(
tempLeftList,
sortThisList.sublist(0, middle),
middle,
);
// Right side.
mSort(
tempRightList,
sortThisList.sublist(middle),
sortThisList.length - middle,
);
// Merge it.
dartMerge(
tempLeftList,
tempRightList,
sortThisList,
);
}
dartMerge(
List<int> leftSide,
List<int> rightSide,
List<int> sortThisList,
) {
int index = 0;
int elementValue;
// This should be human readable.
while (leftSide.isNotEmpty && rightSide.isNotEmpty) {
if (rightSide[0] < leftSide[0]) {
elementValue = rightSide[0];
rightSide.removeRange(0, 1);
} else {
elementValue = leftSide[0];
leftSide.removeRange(0, 1);
}
sortThisList[index++] = elementValue;
}
while (leftSide.isNotEmpty) {
elementValue = leftSide[0];
leftSide.removeRange(0, 1);
sortThisList[index++] = elementValue;
}
while (rightSide.isNotEmpty) {
elementValue = rightSide[0];
rightSide.removeRange(0, 1);
sortThisList[index++] = elementValue;
}
sortedList = sortThisList;
}
}

View file

@ -0,0 +1,20 @@
def merge(var xs :List, var ys :List) {
var result := []
while (xs =~ [x] + xr && ys =~ [y] + yr) {
if (x <= y) {
result with= x
xs := xr
} else {
result with= y
ys := yr
}
}
return result + xs + ys
}
def sort(list :List) {
if (list.size() <= 1) { return list }
def split := list.size() // 2
return merge(sort(list.run(0, split)),
sort(list.run(split)))
}

View file

@ -0,0 +1,92 @@
PROGRAM MERGESORT_DEMO
! Example of merge sort usage.
CONST SIZE%=100,S1%=50
DIM DTA%[SIZE%],FH%[S1%],STACK%[20,2]
PROCEDURE MERGE(START%,MIDDLE%,ENDS%)
LOCAL FHSIZE%
FHSIZE%=MIDDLE%-START%+1
FOR I%=0 TO FHSIZE%-1 DO
FH%[I%]=DTA%[START%+I%]
END FOR
I%=0
J%=MIDDLE%+1
K%=START%
REPEAT
IF FH%[I%]<=DTA%[J%] THEN
DTA%[K%]=FH%[I%]
I%=I%+1
K%=K%+1
ELSE
DTA%[K%]=DTA%[J%]
J%=J%+1
K%=K%+1
END IF
UNTIL I%=FHSIZE% OR J%>ENDS%
WHILE I%<FHSIZE% DO
DTA%[K%]=FH%[I%]
I%=I%+1
K%=K%+1
END WHILE
END PROCEDURE
PROCEDURE MERGE_SORT(LEV->LEV)
! *****************************************************************
! This procedure Merge Sorts the chunk of DTA% bounded by
! Start% & Ends%.
! *****************************************************************
LOCAL MIDDLE%
IF ENDS%=START% THEN LEV=LEV-1 EXIT PROCEDURE END IF
IF ENDS%-START%=1 THEN
IF DTA%[ENDS%]<DTA%[START%] THEN
SWAP(DTA%[START%],DTA%[ENDS%])
END IF
LEV=LEV-1
EXIT PROCEDURE
END IF
MIDDLE%=START%+(ENDS%-START%)/2
STACK%[LEV,0]=START% STACK%[LEV,1]=ENDS% STACK%[LEV,2]=MIDDLE%
START%=START% ENDS%=MIDDLE%
MERGE_SORT(LEV+1->LEV)
START%=STACK%[LEV,0] ENDS%=STACK%[LEV,1] MIDDLE%=STACK%[LEV,2]
STACK%[LEV,0]=START% STACK%[LEV,1]=ENDS% STACK%[LEV,2]=MIDDLE%
START%=MIDDLE%+1 ENDS%=ENDS%
MERGE_SORT(LEV+1->LEV)
START%=STACK%[LEV,0] ENDS%=STACK%[LEV,1] MIDDLE%=STACK%[LEV,2]
MERGE(START%,MIDDLE%,ENDS%)
LEV=LEV-1
END PROCEDURE
BEGIN
FOR I%=1 TO SIZE% DO
DTA%[I%]=RND(1)*10000
END FOR
START%=1 ENDS%=SIZE%
MERGE_SORT(0->LEV)
FOR I%=1 TO SIZE% DO
WRITE("#####";DTA%[I%];)
END FOR
PRINT
END PROGRAM

View file

@ -0,0 +1,35 @@
proc sort . d[] .
len tmp[] len d[]
sz = 1
while sz < len d[]
swap tmp[] d[]
left = 1
while left < len d[]
# merge
mid = left + sz - 1
if mid > len d[]
mid = len d[]
.
right = mid + sz
if right > len d[]
right = len d[]
.
l = left
r = mid + 1
for i = left to right
if r > right or l <= mid and tmp[l] < tmp[r]
d[i] = tmp[l]
l += 1
else
d[i] = tmp[r]
r += 1
.
.
left += 2 * sz
.
sz *= 2
.
.
data[] = [ 29 4 72 44 55 26 27 77 92 5 ]
call sort data[]
print data[]

View file

@ -0,0 +1,120 @@
class
MERGE_SORT [G -> COMPARABLE]
create
sort
feature
sort (ar: ARRAY [G])
-- Sorted array in ascending order.
require
ar_not_empty: not ar.is_empty
do
create sorted_array.make_empty
mergesort (ar, 1, ar.count)
sorted_array := ar
ensure
sorted_array_not_empty: not sorted_array.is_empty
sorted: is_sorted (sorted_array, 1, sorted_array.count)
end
sorted_array: ARRAY [G]
feature {NONE}
mergesort (ar: ARRAY [G]; l, r: INTEGER)
-- Sorting part of mergesort.
local
m: INTEGER
do
if l < r then
m := (l + r) // 2
mergesort (ar, l, m)
mergesort (ar, m + 1, r)
merge (ar, l, m, r)
end
end
merge (ar: ARRAY [G]; l, m, r: INTEGER)
-- Merge part of mergesort.
require
positive_index_l: l >= 1
positive_index_m: m >= 1
positive_index_r: r >= 1
ar_not_empty: not ar.is_empty
local
merged: ARRAY [G]
h, i, j, k: INTEGER
do
i := l
j := m + 1
k := l
create merged.make_filled (ar [1], 1, ar.count)
from
until
i > m or j > r
loop
if ar.item (i) <= ar.item (j) then
merged.force (ar.item (i), k)
i := i + 1
elseif ar.item (i) > ar.item (j) then
merged.force (ar.item (j), k)
j := j + 1
end
k := k + 1
end
if i > m then
from
h := j
until
h > r
loop
merged.force (ar.item (h), k + h - j)
h := h + 1
end
elseif j > m then
from
h := i
until
h > m
loop
merged.force (ar.item (h), k + h - i)
h := h + 1
end
end
from
h := l
until
h > r
loop
ar.item (h) := merged.item (h)
h := h + 1
end
ensure
is_partially_sorted: is_sorted (ar, l, r)
end
is_sorted (ar: ARRAY [G]; l, r: INTEGER): BOOLEAN
-- Is 'ar' sorted in ascending order?
require
ar_not_empty: not ar.is_empty
l_in_range: l >= 1
r_in_range: r <= ar.count
local
i: INTEGER
do
Result := True
from
i := l
until
i = r
loop
if ar [i] > ar [i + 1] then
Result := False
end
i := i + 1
end
end
end

View file

@ -0,0 +1,31 @@
class
APPLICATION
create
make
feature
make
do
test := <<2, 5, 66, -2, 0, 7>>
io.put_string ("unsorted" + "%N")
across
test as ar
loop
io.put_string (ar.item.out + "%T")
end
io.put_string ("%N" + "sorted" + "%N")
create merge.sort (test)
across
merge.sorted_array as ar
loop
io.put_string (ar.item.out + "%T")
end
end
test: ARRAY [INTEGER]
merge: MERGE_SORT [INTEGER]
end

View file

@ -0,0 +1,7 @@
defmodule Sort do
def merge_sort(list) when length(list) <= 1, do: list
def merge_sort(list) do
{left, right} = Enum.split(list, div(length(list), 2))
:lists.merge( merge_sort(left), merge_sort(right))
end
end

View file

@ -0,0 +1,4 @@
mergeSort(L) when length(L) == 1 -> L;
mergeSort(L) when length(L) > 1 ->
{L1, L2} = lists:split(length(L) div 2, L),
lists:merge(mergeSort(L1), mergeSort(L2)).

View file

@ -0,0 +1,13 @@
pMergeSort(L) when length(L) == 1 -> L;
pMergeSort(L) when length(L) > 1 ->
{L1, L2} = lists:split(length(L) div 2, L),
spawn(mergesort, pMergeSort2, [L1, self()]),
spawn(mergesort, pMergeSort2, [L2, self()]),
mergeResults([]).
pMergeSort2(L, Parent) when length(L) == 1 -> Parent ! L;
pMergeSort2(L, Parent) when length(L) > 1 ->
{L1, L2} = lists:split(length(L) div 2, L),
spawn(mergesort, pMergeSort2, [L1, self()]),
spawn(mergesort, pMergeSort2, [L2, self()]),
Parent ! mergeResults([]).

View file

@ -0,0 +1,20 @@
merge_sort(List) -> m(List, erlang:system_info(schedulers)).
m([L],_) -> [L];
m(L, N) when N > 1 ->
{L1,L2} = lists:split(length(L) div 2, L),
{Parent, Ref} = {self(), make_ref()},
spawn(fun()-> Parent ! {l1, Ref, m(L1, N-2)} end),
spawn(fun()-> Parent ! {l2, Ref, m(L2, N-2)} end),
{L1R, L2R} = receive_results(Ref, undefined, undefined),
lists:merge(L1R, L2R);
m(L, _) -> {L1,L2} = lists:split(length(L) div 2, L), lists:merge(m(L1, 0), m(L2, 0)).
receive_results(Ref, L1, L2) ->
receive
{l1, Ref, L1R} when L2 == undefined -> receive_results(Ref, L1R, L2);
{l2, Ref, L2R} when L1 == undefined -> receive_results(Ref, L1, L2R);
{l1, Ref, L1R} -> {L1R, L2};
{l2, Ref, L2R} -> {L1, L2R}
after 5000 -> receive_results(Ref, L1, L2)
end.

View file

@ -0,0 +1,37 @@
function merge(sequence left, sequence right)
sequence result
result = {}
while length(left) > 0 and length(right) > 0 do
if compare(left[1], right[1]) <= 0 then
result = append(result, left[1])
left = left[2..$]
else
result = append(result, right[1])
right = right[2..$]
end if
end while
return result & left & right
end function
function mergesort(sequence m)
sequence left, right
integer middle
if length(m) <= 1 then
return m
else
middle = floor(length(m)/2)
left = mergesort(m[1..middle])
right = mergesort(m[middle+1..$])
if compare(left[$], right[1]) <= 0 then
return left & right
elsif compare(right[$], left[1]) <= 0 then
return right & left
else
return merge(left, right)
end if
end if
end function
constant s = rand(repeat(1000,10))
? s
? mergesort(s)

View file

@ -0,0 +1,22 @@
let split list =
let rec aux l acc1 acc2 =
match l with
| [] -> (acc1,acc2)
| [x] -> (x::acc1,acc2)
| x::y::tail ->
aux tail (x::acc1) (y::acc2)
in aux list [] []
let rec merge l1 l2 =
match (l1,l2) with
| (x,[]) -> x
| ([],y) -> y
| (x::tx,y::ty) ->
if x <= y then x::merge tx l2
else y::merge l1 ty
let rec mergesort list =
match list with
| [] -> []
| [x] -> [x]
| _ -> let (l1,l2) = split list
in merge (mergesort l1) (mergesort l2)

View file

@ -0,0 +1,16 @@
: mergestep ( accum seq1 seq2 -- accum seq1 seq2 )
2dup [ first ] bi@ <
[ [ [ first ] [ rest-slice ] bi [ suffix ] dip ] dip ]
[ [ first ] [ rest-slice ] bi [ swap [ suffix ] dip ] dip ]
if ;
: merge ( seq1 seq2 -- merged )
[ { } ] 2dip
[ 2dup [ length 0 > ] bi@ and ]
[ mergestep ] while
append append ;
: mergesort ( seq -- sorted )
dup length 1 >
[ dup length 2 / floor [ head ] [ tail ] 2bi [ mergesort ] bi@ merge ]
[ ] if ;

View file

@ -0,0 +1,2 @@
( scratchpad ) { 4 2 6 5 7 1 3 } mergesort .
{ 1 2 3 4 5 6 7 }

View file

@ -0,0 +1,23 @@
: merge-step ( right mid left -- right mid+ left+ )
over @ over @ < if
over @ >r
2dup - over dup cell+ rot move
r> over !
>r cell+ 2dup = if rdrop dup else r> then
then cell+ ;
: merge ( right mid left -- right left )
dup >r begin 2dup > while merge-step repeat 2drop r> ;
: mid ( l r -- mid ) over - 2/ cell negate and + ;
: mergesort ( right left -- right left )
2dup cell+ <= if exit then
swap 2dup mid recurse rot recurse merge ;
: sort ( addr len -- ) cells over + swap mergesort 2drop ;
create test 8 , 1 , 5 , 3 , 9 , 0 , 2 , 7 , 6 , 4 ,
: .array ( addr len -- ) 0 do dup i cells + @ . loop drop ;
test 10 2dup sort .array \ 0 1 2 3 4 5 6 7 8 9

View file

@ -0,0 +1,68 @@
program TestMergeSort
implicit none
integer, parameter :: N = 8
integer :: A(N) = (/ 1, 5, 2, 7, 3, 9, 4, 6 /)
integer :: work((size(A) + 1) / 2)
write(*,'(A,/,10I3)')'Unsorted array :',A
call MergeSort(A, work)
write(*,'(A,/,10I3)')'Sorted array :',A
contains
subroutine merge(A, B, C)
implicit none
! The targe attribute is necessary, because A .or. B might overlap with C.
integer, target, intent(in) :: A(:), B(:)
integer, target, intent(inout) :: C(:)
integer :: i, j, k
if (size(A) + size(B) > size(C)) stop(1)
i = 1; j = 1
do k = 1, size(C)
if (i <= size(A) .and. j <= size(B)) then
if (A(i) <= B(j)) then
C(k) = A(i)
i = i + 1
else
C(k) = B(j)
j = j + 1
end if
else if (i <= size(A)) then
C(k) = A(i)
i = i + 1
else if (j <= size(B)) then
C(k) = B(j)
j = j + 1
end if
end do
end subroutine merge
subroutine swap(x, y)
implicit none
integer, intent(inout) :: x, y
integer :: tmp
tmp = x; x = y; y = tmp
end subroutine
recursive subroutine MergeSort(A, work)
implicit none
integer, intent(inout) :: A(:)
integer, intent(inout) :: work(:)
integer :: half
half = (size(A) + 1) / 2
if (size(A) < 2) then
continue
else if (size(A) == 2) then
if (A(1) > A(2)) then
call swap(A(1), A(2))
end if
else
call MergeSort(A( : half), work)
call MergeSort(A(half + 1 :), work)
if (A(half) > A(half + 1)) then
work(1 : half) = A(1 : half)
call merge(work(1 : half), A(half + 1:), A)
endif
end if
end subroutine MergeSort
end program TestMergeSort

View file

@ -0,0 +1,74 @@
' FB 1.05.0 Win64
Sub copyArray(a() As Integer, iBegin As Integer, iEnd As Integer, b() As Integer)
Redim b(iBegin To iEnd - 1) As Integer
For k As Integer = iBegin To iEnd - 1
b(k) = a(k)
Next
End Sub
' Left source half is a(iBegin To iMiddle-1).
' Right source half is a(iMiddle To iEnd-1).
' Result is b(iBegin To iEnd-1).
Sub topDownMerge(a() As Integer, iBegin As Integer, iMiddle As Integer, iEnd As Integer, b() As Integer)
Dim i As Integer = iBegin
Dim j As Integer = iMiddle
' While there are elements in the left or right runs...
For k As Integer = iBegin To iEnd - 1
' If left run head exists and is <= existing right run head.
If i < iMiddle AndAlso (j >= iEnd OrElse a(i) <= a(j)) Then
b(k) = a(i)
i += 1
Else
b(k) = a(j)
j += 1
End If
Next
End Sub
' Sort the given run of array a() using array b() as a source.
' iBegin is inclusive; iEnd is exclusive (a(iEnd) is not in the set).
Sub topDownSplitMerge(b() As Integer, iBegin As Integer, iEnd As Integer, a() As Integer)
If (iEnd - iBegin) < 2 Then Return '' If run size = 1, consider it sorted
' split the run longer than 1 item into halves
Dim iMiddle As Integer = (iEnd + iBegin) \ 2 '' iMiddle = mid point
' recursively sort both runs from array a() into b()
topDownSplitMerge(a(), iBegin, iMiddle, b()) '' sort the left run
topDownSplitMerge(a(), iMiddle, iEnd, b()) '' sort the right run
' merge the resulting runs from array b() into a()
topDownMerge(b(), iBegin, iMiddle, iEnd, a())
End Sub
' Array a() has the items to sort; array b() is a work array (empty initially).
Sub topDownMergeSort(a() As Integer, b() As Integer, n As Integer)
copyArray(a(), 0, n, b()) '' duplicate array a() into b()
topDownSplitMerge(b(), 0, n, a()) '' sort data from b() into a()
End Sub
Sub printArray(a() As Integer)
For i As Integer = LBound(a) To UBound(a)
Print Using "####"; a(i);
Next
Print
End Sub
Dim a(0 To 9) As Integer = {4, 65, 2, -31, 0, 99, 2, 83, 782, 1}
Dim b() As Integer
Print "Unsorted : ";
printArray(a())
topDownMergeSort a(), b(), 10
Print "Sorted : ";
printArray(a())
Print
Dim a2(0 To 8) As Integer = {7, 5, 2, 6, 1, 4, 2, 6, 3}
Erase b
Print "Unsorted : ";
printArray(a2())
topDownMergeSort a2(), b(), 9
Print "Sorted : ";
printArray(a2())
Print
Print "Press any key to quit"
Sleep

View file

@ -0,0 +1,15 @@
def
sort( [] ) = []
sort( [x] ) = [x]
sort( xs ) =
val (l, r) = xs.splitAt( xs.length()\2 )
merge( sort(l), sort(r) )
merge( [], xs ) = xs
merge( xs, [] ) = xs
merge( x:xs, y:ys )
| x <= y = x : merge( xs, y:ys )
| otherwise = y : merge( x:xs, ys )
println( sort([94, 37, 16, 56, 72, 48, 17, 27, 58, 67]) )
println( sort(['Sofía', 'Alysha', 'Sophia', 'Maya', 'Emma', 'Olivia', 'Emily']) )

View file

@ -0,0 +1,44 @@
package main
import "fmt"
var a = []int{170, 45, 75, -90, -802, 24, 2, 66}
var s = make([]int, len(a)/2+1) // scratch space for merge step
func main() {
fmt.Println("before:", a)
mergeSort(a)
fmt.Println("after: ", a)
}
func mergeSort(a []int) {
if len(a) < 2 {
return
}
mid := len(a) / 2
mergeSort(a[:mid])
mergeSort(a[mid:])
if a[mid-1] <= a[mid] {
return
}
// merge step, with the copy-half optimization
copy(s, a[:mid])
l, r := 0, mid
for i := 0; ; i++ {
if s[l] <= a[r] {
a[i] = s[l]
l++
if l == mid {
break
}
} else {
a[i] = a[r]
r++
if r == len(a) {
copy(a[i+1:], s[l:mid])
break
}
}
}
return
}

View file

@ -0,0 +1,26 @@
def merge = { List left, List right ->
List mergeList = []
while (left && right) {
print "."
mergeList << ((left[-1] > right[-1]) ? left.pop() : right.pop())
}
mergeList = mergeList.reverse()
mergeList = left + right + mergeList
}
def mergeSort;
mergeSort = { List list ->
def n = list.size()
if (n < 2) return list
def middle = n.intdiv(2)
def left = [] + list[0..<middle]
def right = [] + list[middle..<n]
left = mergeSort(left)
right = mergeSort(right)
if (left[-1] <= right[0]) return left + right
merge(left, right)
}

View file

@ -0,0 +1,9 @@
println (mergeSort([23,76,99,58,97,57,35,89,51,38,95,92,24,46,31,24,14,12,57,78,4]))
println (mergeSort([88,18,31,44,4,0,8,81,14,78,20,76,84,33,73,75,82,5,62,70,12,7,1]))
println ()
println (mergeSort([10, 10.0, 10.00, 1]))
println (mergeSort([10, 10.00, 10.0, 1]))
println (mergeSort([10.0, 10, 10.00, 1]))
println (mergeSort([10.0, 10.00, 10, 1]))
println (mergeSort([10.00, 10, 10.0, 1]))
println (mergeSort([10.00, 10.0, 10, 1]))

View file

@ -0,0 +1,19 @@
split = { list ->
list.collate((list.size()+1)/2 as int)
}
merge = { left, right, headBuffer=[] ->
if(left.size() == 0) headBuffer+right
else if(right.size() == 0) headBuffer+left
else if(left.head() <= right.head()) merge.trampoline(left.tail(), right, headBuffer+left.head())
else merge.trampoline(right.tail(), left, headBuffer+right.head())
}.trampoline()
mergesort = { List list ->
if(list.size() < 2) list
else merge(split(list).collect {mergesort it})
}
assert mergesort((500..1)) == (1..500)
assert mergesort([5,4,6,3,1,2]) == [1,2,3,4,5,6]
assert mergesort([3,3,1,4,6,78,9,1,3,5]) == [1,1,3,3,3,4,5,6,9,78]

View file

@ -0,0 +1,4 @@
split = { list, left=[], right=[] ->
if(list.size() <2) [list+left, right]
else split.trampoline(list.tail().tail(), [list.head()]+left,[list.tail().head()]+right)
}.trampoline()

View file

@ -0,0 +1,13 @@
merge [] ys = ys
merge xs [] = xs
merge xs@(x:xt) ys@(y:yt) | x <= y = x : merge xt ys
| otherwise = y : merge xs yt
split (x:y:zs) = let (xs,ys) = split zs in (x:xs,y:ys)
split [x] = ([x],[])
split [] = ([],[])
mergeSort [] = []
mergeSort [x] = [x]
mergeSort xs = let (as,bs) = split xs
in merge (mergeSort as) (mergeSort bs)

View file

@ -0,0 +1,7 @@
mergePairs (sorted1 : sorted2 : sorteds) = merge sorted1 sorted2 : mergePairs sorteds
mergePairs sorteds = sorteds
mergeSortBottomUp list = mergeAll (map (\x -> [x]) list)
mergeAll [sorted] = sorted
mergeAll sorteds = mergeAll (mergePairs sorteds)

View file

@ -0,0 +1,15 @@
sort = sortBy compare
sortBy cmp = mergeAll . sequences
where
sequences (a:b:xs)
| a `cmp` b == GT = descending b [a] xs
| otherwise = ascending b (a:) xs
sequences xs = [xs]
descending a as (b:bs)
| a `cmp` b == GT = descending b (a:as) bs
descending a as bs = (a:as): sequences bs
ascending a as (b:bs)
| a `cmp` b /= GT = ascending b (\ys -> as (a:ys)) bs
ascending a as bs = as [a]: sequences bs

View file

@ -0,0 +1,49 @@
procedure main() #: demonstrate various ways to sort a list and string
demosort(mergesort,[3, 14, 1, 5, 9, 2, 6, 3],"qwerty")
end
procedure mergesort(X,op,lower,upper) #: return sorted list ascending(or descending)
local middle
if /lower := 1 then { # top level call setup
upper := *X
op := sortop(op,X) # select how and what we sort
}
if upper ~= lower then { # sort all sections with 2 or more elements
X := mergesort(X,op,lower,middle := lower + (upper - lower) / 2)
X := mergesort(X,op,middle+1,upper)
if op(X[middle+1],X[middle]) then # @middle+1 < @middle merge if halves reversed
X := merge(X,op,lower,middle,upper)
}
return X
end
procedure merge(X,op,lower,middle,upper) # merge two list sections within a larger list
local p1,p2,add
p1 := lower
p2 := middle + 1
add := if type(X) ~== "string" then put else "||" # extend X, strings require X := add (until ||:= is invocable)
while p1 <= middle & p2 <= upper do
if op(X[p1],X[p2]) then { # @p1 < @p2
X := add(X,X[p1]) # extend X temporarily (rather than use a separate temporary list)
p1 +:= 1
}
else {
X := add(X,X[p2]) # extend X temporarily
p2 +:= 1
}
while X := add(X,X[middle >= p1]) do p1 +:= 1 # and rest of lower or ...
while X := add(X,X[upper >= p2]) do p2 +:= 1 # ... upper trailers if any
if type(X) ~== "string" then # pull section's sorted elements from extension
every X[upper to lower by -1] := pull(X)
else
(X[lower+:(upper-lower+1)] := X[0-:(upper-lower+1)])[0-:(upper-lower+1)] := ""
return X
end

View file

@ -0,0 +1,28 @@
List do (
merge := method(lst1, lst2,
result := list()
while(lst1 isNotEmpty or lst2 isNotEmpty,
if(lst1 first <= lst2 first) then(
result append(lst1 removeFirst)
) else (
result append(lst2 removeFirst)
)
)
result)
mergeSort := method(
if (size > 1) then(
half_size := (size / 2) ceil
return merge(slice(0, half_size) mergeSort,
slice(half_size, size) mergeSort)
) else (return self)
)
mergeSortInPlace := method(
copy(mergeSort)
)
)
lst := list(9, 5, 3, -1, 15, -2)
lst mergeSort println # ==> list(-2, -1, 3, 5, 9, 15)
lst mergeSortInPlace println # ==> list(-2, -1, 3, 5, 9, 15)

View file

@ -0,0 +1,97 @@
theory Mergesort
  imports Main
begin
fun merge :: "int list ⇒ int list ⇒ int list" where
  "merge [] ys = ys"
| "merge xs [] = xs"
| "merge (x#xs) (y#ys) = (if x ≤ y
                          then x # merge xs (y#ys)
                          else y # merge (x # xs) ys)"
textexample:
lemma "merge [1,3,6] [1,2,5,8] = [1,1,2,3,5,6,8]" by simp
lemma merge_set: "set (merge xs ys) = set xs set ys"
  by(induction xs ys rule: merge.induct) auto
lemma merge_sorted:
  "sorted xs ⟹ sorted ys ⟹ sorted (merge xs ys)"
proof(induction xs ys rule: merge.induct)
  case (1 ys)
  then show "sorted (merge [] ys)" by simp
next
  case (2 x xs)
  then show "sorted (merge (x # xs) [])" by simp
next
  case (3 x xs y ys)
  assume premx: "sorted (x # xs)"
     and premy: "sorted (y # ys)"
     and IHx: "x ≤ y ⟹ sorted xs ⟹ sorted (y # ys) ⟹
                 sorted (merge xs (y # ys))"
     and IHy: "¬ x ≤ y ⟹ sorted (x # xs) ⟹ sorted ys ⟹
                 sorted (merge (x # xs) ys)"
  then show "sorted (merge (x # xs) (y # ys))"
  proof(cases "x ≤ y")
    case True
    with premx IHx premy have IH: "sorted (merge xs (y # ys))" by simp
    from x ≤ y premx premy merge_set have
      "∀z ∈ set (merge xs (y # ys)). x ≤ z" by fastforce
    with x ≤ y IH show "sorted (merge (x # xs) (y # ys))" by(simp)
  next
    case False
    with premy IHy premx have IH: "sorted (merge (x # xs) ys)" by simp
    from ¬x ≤ y premx premy merge_set have
      "∀z ∈ set (merge (x # xs) ys). y ≤ z" by fastforce
    with ¬x ≤ y IH show "sorted (merge (x # xs) (y # ys))" by(simp)
  qed
qed
fun mergesort :: "int list ⇒ int list" where
  "mergesort [] = []"
| "mergesort [x] = [x]"
| "mergesort xs = merge (mergesort (take (length xs div 2) xs))
                        (mergesort (drop (length xs div 2) xs))"
theorem mergesort_set: "set xs = set (mergesort xs)"
proof(induction xs rule: mergesort.induct)
  case 1
  show "set [] = set (mergesort [])" by simp
next
  case (2 x)
  show "set [x] = set (mergesort [x])" by simp
next
  case (3 x1 x2 xs)
  from 3 have IH_simplified_take:
    "set (mergesort (x1 # take (length xs div 2) (x2 # xs))) =
     insert x1 (set (take (length xs div 2) (x2 # xs)))"
  and IH_simplified_drop:
    "set (mergesort (drop (length xs div 2) (x2 # xs))) =
     set (drop (length xs div 2) (x2 # xs))" by simp+
  have "(set (take n as) set (drop n as)) = set as"
    for n and as::"int list"
  proof -
    from set_append[of "take n as" "drop n as"] have
      "(set (take n as) set (drop n as)) =
       set (take n as @ drop n as)" by simp
    moreover have
      "set (take n as @ drop n as) =
       set as" using append_take_drop_id by simp
    ultimately show ?thesis by simp
  qed
  hence "(set (take (length xs div 2) (x2 # xs))
        set (drop (length xs div 2) (x2 # xs))) =
        set (x2 # xs)"by(simp)
  with IH_simplified_take IH_simplified_drop show
    "set (x1 # x2 # xs) = set (mergesort (x1 # x2 # xs))"
    by(simp add: merge_set)
qed
theorem mergesort_sorted: "sorted (mergesort xs)"
  by(induction xs rule: mergesort.induct) (simp add: merge_sorted)+
textexample:
lemma "mergesort [42, 5, 1, 3, 67, 3, 9, 0, 33, 32] =
                 [0, 1, 3, 3, 5, 9, 32, 33, 42, 67]" by simp
end

View file

@ -0,0 +1,16 @@
mergesort=: {{
if. 2>#y do. y return.end.
middle=. <.-:#y
X=. mergesort middle{.y
Y=. mergesort middle}.y
X merge Y
}}
merge=: {{ r=. y#~ i=. j=. 0
while. (i<#x)*(j<#y) do. a=. i{x [b=. j{y
if. a<b do. r=. r,a [i=. i+1
else. r=. r,b [j=. j+1 end.
end.
if. i<#x do. r=. r, i}.x end.
if. j<#y do. r=. r, j}.y end.
}}

View file

@ -0,0 +1,5 @@
mergesort=: {{ r=. y [ stride=. 1
while. stride < #r do. stride=. 2*mid=. stride
r=. ;(-stride) (mid&}. <@merge (mid<.#) {.])\ r
end.
}}

View file

@ -0,0 +1,2 @@
mergesort 18 2 8 1 5 14 9 19 11 13 16 0 3 10 17 15 12 4 7 6
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

View file

@ -0,0 +1,2 @@
(/:~ -: mergesort) ?~?10000
1

View file

@ -0,0 +1,3 @@
case=. 1 * (0 = # x=. @:[) + 2 * (0 = # y=. @:])
merge=. ({.x , }.x $: ])`(({.y , }.y $: [))@.({.x > {.y)`]`[@.case
mergesort=. (>: o ? o # ($: o {. merge $: (o=. @:) }.) ]) ^: (1 < #)

View file

@ -0,0 +1,2 @@
mergesort 18 2 8 1 5 14 9 19 11 13 16 0 3 10 17 15 12 4 7 6
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

View file

@ -0,0 +1,55 @@
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
public class Merge{
public static <E extends Comparable<? super E>> List<E> mergeSort(List<E> m){
if(m.size() <= 1) return m;
int middle = m.size() / 2;
List<E> left = m.subList(0, middle);
List<E> right = m.subList(middle, m.size());
right = mergeSort(right);
left = mergeSort(left);
List<E> result = merge(left, right);
return result;
}
public static <E extends Comparable<? super E>> List<E> merge(List<E> left, List<E> right){
List<E> result = new ArrayList<E>();
Iterator<E> it1 = left.iterator();
Iterator<E> it2 = right.iterator();
E x = it1.next();
E y = it2.next();
while (true){
//change the direction of this comparison to change the direction of the sort
if(x.compareTo(y) <= 0){
result.add(x);
if(it1.hasNext()){
x = it1.next();
}else{
result.add(y);
while(it2.hasNext()){
result.add(it2.next());
}
break;
}
}else{
result.add(y);
if(it2.hasNext()){
y = it2.next();
}else{
result.add(x);
while (it1.hasNext()){
result.add(it1.next());
}
break;
}
}
}
return result;
}
}

View file

@ -0,0 +1,75 @@
function mergeSort(v) {
if (v.length <= 1) {
return v;
}
let m = Math.floor(v.length / 2);
let l = mergeSort(v.slice(0, m));
let r = mergeSort(v.slice(m));
return merge(l, r);
function merge(a, b) {
let i = 0, j = 0;
let n = a.length + b.length;
let c = [];
while (c.length < n) {
if (i < a.length && (j >= b.length || a[i] < b[j])) {
c.push(a[i++]);
} else {
c.push(b[j++]);
}
}
return c;
}
}
function mergeSortInPlace(v) {
if (v.length <= 1) {
return;
}
let m = Math.floor(v.length / 2);
let l = v.slice(0, m);
let r = v.slice(m);
mergeSortInPlace(l);
mergeSortInPlace(r);
merge(l, r, v);
// merge a + b -> c
function merge(a, b, c) {
let i = 0, j = 0;
for (let k = 0; k < c.length; k++) {
if (i < a.length && (j >= b.length || a[i] < b[j])) {
c[k] = a[i++];
} else {
c[k] = b[j++];
}
}
}
}
// even faster
function mergeSortInPlaceFast(v) {
sort(v, 0, v.length, v.slice());
function sort(v, lo, hi, t) {
let n = hi - lo;
if (n <= 1) {
return;
}
let mid = lo + Math.floor(n / 2);
sort(v, lo, mid, t);
sort(v, mid, hi, t);
for (let i = lo; i < hi; i++) {
t[i] = v[i];
}
let i = lo, j = mid;
for (let k = lo; k < hi; k++) {
if (i < mid && (j >= hi || t[i] < t[j])) {
v[k] = t[i++];
} else {
v[k] = t[j++];
}
}
}
}

View file

@ -0,0 +1,46 @@
function merge(left, right, arr) {
var a = 0;
while (left.length && right.length) {
arr[a++] = (right[0] < left[0]) ? right.shift() : left.shift();
}
while (left.length) {
arr[a++] = left.shift();
}
while (right.length) {
arr[a++] = right.shift();
}
}
function mergeSort(arr) {
var len = arr.length;
if (len === 1) { return; }
var mid = Math.floor(len / 2),
left = arr.slice(0, mid),
right = arr.slice(mid);
mergeSort(left);
mergeSort(right);
merge(left, right, arr);
}
var arr = [1, 5, 2, 7, 3, 9, 4, 6, 8];
mergeSort(arr); // arr will now: 1, 2, 3, 4, 5, 6, 7, 8, 9
// here is improved faster version, also often faster than QuickSort!
function mergeSort2(a) {
if (a.length <= 1) return
const mid = Math.floor(a.length / 2), left = a.slice(0, mid), right = a.slice(mid)
mergeSort2(left)
mergeSort2(right)
let ia = 0, il = 0, ir = 0
while (il < left.length && ir < right.length)
a[ia++] = left[il] < right[ir] ? left[il++] : right[ir++]
while (il < left.length)
a[ia++] = left[il++]
while (ir < right.length)
a[ia++] = right[ir++]
}

View file

@ -0,0 +1,22 @@
# Input: [x,y] -- the two arrays to be merged
# If x and y are sorted as by "sort", then the result will also be sorted:
def merge:
def m: # state: [x, y, array] (array being the answer)
.[0] as $x
| .[1] as $y
| if 0 == ($x|length) then .[2] + $y
elif 0 == ($y|length) then .[2] + $x
else
(if $x[0] <= $y[0] then [$x[1:], $y, .[2] + [$x[0] ]]
else [$x, $y[1:], .[2] + [$y[0] ]]
end) | m
end;
[.[0], .[1], []] | m;
def merge_sort:
if length <= 1 then .
else
(length/2 |floor) as $len
| . as $in
| [ ($in[0:$len] | merge_sort), ($in[$len:] | merge_sort) ] | merge
end;

View file

@ -0,0 +1,4 @@
( [1, 3, 8, 9, 0, 0, 8, 7, 1, 6],
[170, 45, 75, 90, 2, 24, 802, 66],
[170, 45, 75, 90, 2, 24, -802, -66] )
| (merge_sort == sort)

View file

@ -0,0 +1,27 @@
function mergesort(arr::Vector)
if length(arr) ≤ 1 return arr end
mid = length(arr) ÷ 2
lpart = mergesort(arr[1:mid])
rpart = mergesort(arr[mid+1:end])
rst = similar(arr)
i = ri = li = 1
@inbounds while li ≤ length(lpart) && ri ≤ length(rpart)
if lpart[li] ≤ rpart[ri]
rst[i] = lpart[li]
li += 1
else
rst[i] = rpart[ri]
ri += 1
end
i += 1
end
if li ≤ length(lpart)
copy!(rst, i, lpart, li)
else
copy!(rst, i, rpart, ri)
end
return rst
end
v = rand(-10:10, 10)
println("# unordered: $v\n -> ordered: ", mergesort(v))

View file

@ -0,0 +1,50 @@
fun mergeSort(list: List<Int>): List<Int> {
if (list.size <= 1) {
return list
}
val left = mutableListOf<Int>()
val right = mutableListOf<Int>()
val middle = list.size / 2
list.forEachIndexed { index, number ->
if (index < middle) {
left.add(number)
} else {
right.add(number)
}
}
fun merge(left: List<Int>, right: List<Int>): List<Int> = mutableListOf<Int>().apply {
var indexLeft = 0
var indexRight = 0
while (indexLeft < left.size && indexRight < right.size) {
if (left[indexLeft] <= right[indexRight]) {
add(left[indexLeft])
indexLeft++
} else {
add(right[indexRight])
indexRight++
}
}
while (indexLeft < left.size) {
add(left[indexLeft])
indexLeft++
}
while (indexRight < right.size) {
add(right[indexRight])
indexRight++
}
}
return merge(mergeSort(left), mergeSort(right))
}
fun main(args: Array<String>) {
val numbers = listOf(5, 2, 3, 17, 12, 1, 8, 3, 4, 9, 7)
println("Unsorted: $numbers")
println("Sorted: ${mergeSort(numbers)}")
}

View file

@ -0,0 +1,27 @@
{def alt
{lambda {:list}
{if {A.empty? :list}
then {A.new}
else {A.addfirst! {A.first :list}
{alt {A.rest {A.rest :list}}}} }}}
-> alt
{def merge
{lambda {:l1 :l2}
{if {A.empty? :l2}
then :l1
else {if {< {A.first :l1} {A.first :l2}}
then {A.addfirst! {A.first :l1} {merge :l2 {A.rest :l1}}}
else {A.addfirst! {A.first :l2} {merge :l1 {A.rest :l2}}} }}}}
-> merge
{def mergesort
{lambda {:list}
{if {A.empty? {A.rest :list}}
then :list
else {merge {mergesort {alt :list}}
{mergesort {alt {A.rest :list}}}} }}}
-> mergesort
{mergesort {A.new 8 1 5 3 9 0 2 7 6 4}}
-> [0,1,2,3,4,5,6,7,8,9]

View file

@ -0,0 +1,70 @@
itemCount = 20
dim A(itemCount)
dim tmp(itemCount) 'merge sort needs additionally same amount of storage
for i = 1 to itemCount
A(i) = int(rnd(1) * 100)
next i
print "Before Sort"
call printArray itemCount
call mergeSort 1,itemCount
print "After Sort"
call printArray itemCount
end
'------------------------------------------
sub mergeSort start, theEnd
if theEnd-start < 1 then exit sub
if theEnd-start = 1 then
if A(start)>A(theEnd) then
tmp=A(start)
A(start)=A(theEnd)
A(theEnd)=tmp
end if
exit sub
end if
middle = int((start+theEnd)/2)
call mergeSort start, middle
call mergeSort middle+1, theEnd
call merge start, middle, theEnd
end sub
sub merge start, middle, theEnd
i = start: j = middle+1: k = start
while i<=middle OR j<=theEnd
select case
case i<=middle AND j<=theEnd
if A(i)<=A(j) then
tmp(k)=A(i)
i=i+1
else
tmp(k)=A(j)
j=j+1
end if
k=k+1
case i<=middle
tmp(k)=A(i)
i=i+1
k=k+1
case else 'j<=theEnd
tmp(k)=A(j)
j=j+1
k=k+1
end select
wend
for i = start to theEnd
A(i)=tmp(i)
next
end sub
'===========================================
sub printArray itemCount
for i = 1 to itemCount
print using("###", A(i));
next i
print
end sub

View file

@ -0,0 +1,17 @@
to split :size :front :list
if :size < 1 [output list :front :list]
output split :size-1 (lput first :list :front) (butfirst :list)
end
to merge :small :large
if empty? :small [output :large]
ifelse lessequal? first :small first :large ~
[output fput first :small merge butfirst :small :large] ~
[output fput first :large merge butfirst :large :small]
end
to mergesort :list
localmake "half split (count :list) / 2 [] :list
if empty? first :half [output :list]
output merge mergesort first :half mergesort last :half
end

View file

@ -0,0 +1,20 @@
msort([], []) :- !.
msort([X], [X]) :- !.
msort([X, Y| Xs], Ys) :-
split([X, Y| Xs], X1s, X2s),
msort(X1s, Y1s),
msort(X2s, Y2s),
merge(Y1s, Y2s, Ys).
split([], [], []).
split([X| Xs], [X| Ys], Zs) :-
split(Xs, Zs, Ys).
merge([X| Xs], [Y| Ys], [X| Zs]) :-
X @=< Y, !,
merge(Xs, [Y| Ys], Zs).
merge([X| Xs], [Y| Ys], [Y| Zs]) :-
X @> Y, !,
merge([X | Xs], Ys, Zs).
merge([], Xs, Xs) :- !.
merge(Xs, [], Xs).

View file

@ -0,0 +1,56 @@
local function merge(left_container, left_container_begin, left_container_end, right_container, right_container_begin, right_container_end, result_container, result_container_begin, comparator)
while left_container_begin <= left_container_end do
if right_container_begin > right_container_end then
for i = left_container_begin, left_container_end do
result_container[result_container_begin] = left_container[i]
result_container_begin = result_container_begin + 1
end
return
end
if comparator(right_container[right_container_begin], left_container[left_container_begin]) then
result_container[result_container_begin] = right_container[right_container_begin]
right_container_begin = right_container_begin + 1
else
result_container[result_container_begin] = left_container[left_container_begin]
left_container_begin = left_container_begin + 1
end
result_container_begin = result_container_begin + 1
end
for i = right_container_begin, right_container_end do
result_container[result_container_begin] = right_container[i]
result_container_begin = result_container_begin + 1
end
end
local function mergesort_impl(container, container_begin, container_end, comparator)
local range_length = (container_end - container_begin) + 1
if range_length < 2 then return end
local copy = {}
local copy_len = 0
for it = container_begin, container_end do
copy_len = copy_len + 1
copy[copy_len] = container[it]
end
local middle = bit.rshift(range_length, 1) -- or math.floor(range_length / 2)
mergesort_impl(copy, 1, middle, comparator)
mergesort_impl(copy, middle + 1, copy_len, comparator)
merge(copy, 1, middle, copy, middle + 1, copy_len, container, container_begin, comparator)
end
local function mergesort_default_comparator(a, b)
return a < b
end
function table.mergesort(container, comparator)
if not comparator then
comparator = mergesort_default_comparator
end
mergesort_impl(container, 1, #container, comparator)
end

View file

@ -0,0 +1,22 @@
function getLower(a,b)
local i,j=1,1
return function()
if not b[j] or a[i] and a[i]<b[j] then
i=i+1; return a[i-1]
else
j=j+1; return b[j-1]
end
end
end
function merge(a,b)
local res={}
for v in getLower(a,b) do res[#res+1]=v end
return res
end
function mergesort(list)
if #list<=1 then return list end
local s=math.floor(#list/2)
return merge(mergesort{unpack(list,1,s)}, mergesort{unpack(list,s+1)})
end

View file

@ -0,0 +1,17 @@
msort(a) = if iseod(first next a) then a else merge(msort(b0),msort(b1)) fi
where
p = false fby not p;
b0 = a whenever p;
b1 = a whenever not p;
just(a) = ja
where
ja = a fby if iseod ja then eod else next a fi;
end;
merge(x,y) = if takexx then xx else yy fi
where
xx = (x) upon takexx;
yy = (y) upon not takexx;
takexx = if iseod(yy) then true elseif
iseod(xx) then false else xx <= yy fi;
end;
end;

View file

@ -0,0 +1,82 @@
module checkit {
\\ merge sort
group merge {
function sort(right as stack) {
if len(right)<=1 then =right : exit
left=.sort(stack up right, len(right) div 2 )
right=.sort(right)
\\ stackitem(right) is same as stackitem(right,1)
if stackitem(left, len(left))<=stackitem(right) then
\\ !left take items from left for merging
\\ so after this left and right became empty stacks
=stack:=!left, !right
exit
end if
=.merge(left, right)
}
function sortdown(right as stack) {
if len(right)<=1 then =right : exit
left=.sortdown(stack up right, len(right) div 2 )
right=.sortdown(right)
if stackitem(left, len(left))>stackitem(right) then
=stack:=!left, !right : exit
end if
=.mergedown(left, right)
}
\\ left and right are pointers to stack objects
\\ here we pass by value the pointer not the data
function merge(left as stack, right as stack) {
result=stack
while len(left) > 0 and len(right) > 0
if stackitem(left,1) <= stackitem(right) then
result=stack:=!result, !(stack up left, 1)
else
result=stack:=!result, !(stack up right, 1)
end if
end while
if len(right) > 0 then result=stack:= !result,!right
if len(left) > 0 then result=stack:= !result,!left
=result
}
function mergedown(left as stack, right as stack) {
result=stack
while len(left) > 0 and len(right) > 0
if stackitem(left,1) > stackitem(right) then
result=stack:=!result, !(stack up left, 1)
else
result=stack:=!result, !(stack up right, 1)
end if
end while
if len(right) > 0 then result=stack:= !result,!right
if len(left) > 0 then result=stack:= !result,!left
=result
}
}
k=stack:=7, 5, 2, 6, 1, 4, 2, 6, 3
print merge.sort(k)
print len(k)=0 ' we have to use merge.sort(stack(k)) to pass a copy of k
\\ input array (arr is a pointer to array)
arr=(10,8,9,7,5,6,2,3,0,1)
\\ stack(array pointer) return a stack with a copy of array items
\\ array(stack pointer) return an array, empty the stack
arr2=array(merge.sort(stack(arr)))
Print type$(arr2)
Dim a()
\\ a() is an array as a value, so we just copy arr2 to a()
a()=arr2
\\ to prove we add 1 to each element of arr2
arr2++
Print a() ' 0,1,2,3,4,5,6,7,8,9
Print arr2 ' 1,2,3,4,5,6,7,8,9,11
p=a() ' we get a pointer
\\ a() has a double pointer inside
\\ so a() get just the inner pointer
a()=array(merge.sortdown(stack(p)))
\\ so now p (which use the outer pointer)
\\ still points to a()
print p ' p point to a()
}
checkit

View file

@ -0,0 +1,38 @@
function list = mergeSort(list)
if numel(list) <= 1
return
else
middle = ceil(numel(list) / 2);
left = list(1:middle);
right = list(middle+1:end);
left = mergeSort(left);
right = mergeSort(right);
if left(end) <= right(1)
list = [left right];
return
end
%merge(left,right)
counter = 1;
while (numel(left) > 0) && (numel(right) > 0)
if(left(1) <= right(1))
list(counter) = left(1);
left(1) = [];
else
list(counter) = right(1);
right(1) = [];
end
counter = counter + 1;
end
if numel(left) > 0
list(counter:end) = left;
elseif numel(right) > 0
list(counter:end) = right;
end
%end merge
end %if
end %mergeSort

View file

@ -0,0 +1,5 @@
>> mergeSort([4 3 1 5 6 2])
ans =
1 2 3 4 5 6

View file

@ -0,0 +1,55 @@
fn mergesort arr =
(
local left = #()
local right = #()
local result = #()
if arr.count < 2 then return arr
else
(
local mid = arr.count/2
for i = 1 to mid do
(
append left arr[i]
)
for i = (mid+1) to arr.count do
(
append right arr[i]
)
left = mergesort left
right = mergesort right
if left[left.count] <= right[1] do
(
join left right
return left
)
result = _merge left right
return result
)
)
fn _merge a b =
(
local result = #()
while a.count > 0 and b.count > 0 do
(
if a[1] <= b[1] then
(
append result a[1]
a = for i in 2 to a.count collect a[i]
)
else
(
append result b[1]
b = for i in 2 to b.count collect b[i]
)
)
if a.count > 0 do
(
join result a
)
if b.count > 0 do
(
join result b
)
return result
)

View file

@ -0,0 +1,4 @@
a = for i in 1 to 15 collect random -5 20
#(-3, 13, 2, -2, 13, 9, 17, 7, 16, 19, 0, 0, 20, 18, 1)
mergeSort a
#(-3, -2, 0, 0, 1, 2, 7, 9, 13, 13, 16, 17, 18, 19, 20)

View file

@ -0,0 +1,39 @@
merge := proc(arr, left, mid, right)
local i, j, k, n1, n2, L, R;
n1 := mid-left+1:
n2 := right-mid:
L := Array(1..n1):
R := Array(1..n2):
for i from 0 to n1-1 do
L(i+1) :=arr(left+i):
end do:
for j from 0 to n2-1 do
R(j+1) := arr(mid+j+1):
end do:
i := 1:
j := 1:
k := left:
while(i <= n1 and j <= n2) do
if (L[i] <= R[j]) then
arr[k] := L[i]:
i++:
else
arr[k] := R[j]:
j++:
end if:
k++:
end do:
while(i <= n1) do
arr[k] := L[i]:
i++:
k++:
end do:
while(j <= n2) do
arr[k] := R[j]:
j++:
k++:
end do:
end proc:
arr := Array([17,3,72,0,36,2,3,8,40,0]);
mergeSort(arr,1,numelems(arr)):
arr;

View file

@ -0,0 +1,19 @@
MergeSort[m_List] := Module[{middle},
If[Length[m] >= 2,
middle = Ceiling[Length[m]/2];
Apply[Merge,
Map[MergeSort, Partition[m, middle, middle, {1, 1}, {}]]],
m
]
]
Merge[left_List, right_List] := Module[
{leftIndex = 1, rightIndex = 1},
Table[
Which[
leftIndex > Length[left], right[[rightIndex++]],
rightIndex > Length[right], left[[leftIndex++]],
left[[leftIndex]] <= right[[rightIndex]], left[[leftIndex++]],
True, right[[rightIndex++]]],
{Length[left] + Length[right]}]
]

View file

@ -0,0 +1,22 @@
merge(a, b) := block(
[c: [ ], i: 1, j: 1, p: length(a), q: length(b)],
while i <= p and j <= q do (
if a[i] < b[j] then (
c: endcons(a[i], c),
i: i + 1
) else (
c: endcons(b[j], c),
j: j + 1
)
),
if i > p then append(c, rest(b, j - 1)) else append(c, rest(a, i - 1))
)$
mergesort(u) := block(
[n: length(u), k, a, b],
if n <= 1 then u else (
a: rest(u, k: quotient(n, 2)),
b: rest(u, k - n),
merge(mergesort(a), mergesort(b))
)
)$

View file

@ -0,0 +1,46 @@
:- module merge_sort.
:- interface.
:- import_module list.
:- type split_error ---> split_error.
:- func merge_sort(list(T)) = list(T).
:- pred merge_sort(list(T)::in, list(T)::out) is det.
:- implementation.
:- import_module int, exception.
merge_sort(U) = S :- merge_sort(U, S).
merge_sort(U, S) :- merge_sort(list.length(U), U, S).
:- pred merge_sort(int::in, list(T)::in, list(T)::out) is det.
merge_sort(L, U, S) :-
( L > 1 ->
H = L // 2,
( split(H, U, F, B) ->
merge_sort(H, F, SF),
merge_sort(L - H, B, SB),
merge_sort.merge(SF, SB, S)
; throw(split_error) )
; S = U ).
:- pred split(int::in, list(T)::in, list(T)::out, list(T)::out) is semidet.
split(N, L, S, E) :-
( N = 0 -> S = [], E = L
; N > 0, L = [H | L1], S = [H | S1],
split(N - 1, L1, S1, E) ).
:- pred merge(list(T)::in, list(T)::in, list(T)::out) is det.
merge([], [], []).
merge([X|Xs], [], [X|Xs]).
merge([], [Y|Ys], [Y|Ys]).
merge([X|Xs], [Y|Ys], M) :-
( compare(>, X, Y) ->
merge_sort.merge([X|Xs], Ys, M0),
M = [Y|M0]
; merge_sort.merge(Xs, [Y|Ys], M0),
M = [X|M0] ).

View file

@ -0,0 +1,85 @@
120 LET N = 10
130 LET C = 0
140 OPTION BASE 1
150 DIM A(10)
160 DIM B(10)
170 RANDOMIZE
180 GOSUB 810
190 REM Print the random array
200 PRINT "unsort ";
210 GOSUB 860
220 REM Sort the array
230 GOSUB 300
240 PRINT " sort ";
250 REM Print the sorted array
260 GOSUB 860
270 PRINT "Number of iterations: "; C
290 GOTO 950
300 REM Merge sort the list A of length N
310 REM Using the array B for temporary storage
320 REM
330 REM === Split phase ===
340 REM C counts the number of split/merge iterations
350 LET C = C+1
360 LET X = 1
370 LET Y = 1
380 LET Z = N
390 GOTO 410
400 IF A(X) < A(X-1) THEN 470
410 LET B(Y) = A(X)
420 LET Y = Y+1
430 LET X = X+1
440 IF Z < Y THEN 500
450 GOTO 400
460 IF A(X) < A(X-1) THEN 410
470 LET B(Z) = A(X)
480 LET Z = Z-1
490 LET X = X+1
500 IF Z < Y THEN 530
510 GOTO 460
520 REM
530 REM === Merge Phase ===
540 REM Q means "we're done" (or "quit")
550 REM Q is 1 until we know that this is _not_ the last iteration
560 LET Q = 1
570 LET X = 1
580 LET Y = 1
590 LET Z = N
600 REM First select the smaller item
610 IF B(Y) < B(Z) THEN 710
615 IF B(Y) > B(Z) THEN 750
620 REM Check if the loop is done
630 IF Z < Y THEN 790
640 REM If both items are smaller then start over with the smallest
650 IF B(Y) >= A(X-1) THEN 680
655 IF B(Z) >= A(X-1) THEN 680
660 LET Q = 0
670 GOTO 600
680 REM Pick the smallest item that represents an increase
690 IF B(Z) < B(Y) THEN 695
692 IF B(Z) > B(Y) THEN 700
695 IF B(Z) >= A(X-1) THEN 750
700 IF B(Z) > B(Y) THEN 705
705 IF B(Y) < A(X-1) THEN 750
710 LET A(X) = B(Y)
720 LET Y = Y+1
730 LET X = X+1
740 GOTO 620
750 LET A(X) = B(Z)
760 LET Z = Z-1
770 LET X = X+1
780 GOTO 620
790 IF Q = 0 THEN 330
800 RETURN
810 REM Create a random list of N integers
820 FOR I = 1 TO N
830 LET A(I) = INT((RND * 100) + .5)
840 NEXT I
850 RETURN
860 REM PRINT the list A
870 FOR I = 1 TO N
880 PRINT A(I); " ";
890 NEXT I
900 PRINT
910 RETURN
950 END

View file

@ -0,0 +1,17 @@
main :: [sys_message]
main = [Stdout ("Before: " ++ show testlist ++ "\n"),
Stdout ("After: " ++ show (mergesort testlist) ++ "\n")]
where testlist = [4,65,2,-31,0,99,2,83,782,1]
mergesort :: [*]->[*]
mergesort [] = []
mergesort [x] = [x]
mergesort xs = merge (mergesort l) (mergesort r)
where (l, r) = split [] [] xs
split l r [] = (l,r)
split l r [x] = (x:l,r)
split l r (x:y:xs) = split (x:l) (y:r) xs
merge xs [] = xs
merge [] ys = ys
merge (x:xs) (y:ys) = x:y:merge xs ys, if x<y
= y:x:merge xs ys, if x>=y

View file

@ -0,0 +1,5 @@
DEFINITION MODULE MSIterat;
PROCEDURE IterativeMergeSort( VAR a : ARRAY OF INTEGER);
END MSIterat.

Some files were not shown because too many files have changed in this diff Show more