2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,11 +1,25 @@
|
|||
{{Sorting Algorithm}}[[Category:Recursion]]The '''merge sort''' is a recursive sort of order n*log(n).
|
||||
It is notable for having a worst case and average complexity of ''O(n*log(n))'', and a best case complexity of ''O(n)'' (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 (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 "divide and conquer" description.
|
||||
{{Sorting Algorithm}}
|
||||
[[Category:Recursion]]
|
||||
|
||||
The '''merge sort''' is a recursive sort of order <big> n*log(n). </big>
|
||||
|
||||
It is notable for having a worst case and average complexity of <big> ''O(n*log(n))'', </big> and a best case complexity of <big> ''O(n)'' </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 (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 ''divide and conquer'' 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 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
|
||||
|
|
@ -40,6 +54,10 @@ The functions in pseudocode look like this:
|
|||
'''append''' rest(right) '''to''' result
|
||||
'''return''' result
|
||||
|
||||
For more information see [[wp:Merge_sort|Wikipedia]]
|
||||
|
||||
Note: better performance can be expected if, rather than recursing until length(m) ≤ 1, an insertion sort is used for length(m) smaller than some threshold larger than 1. However, this complicates example code, so is not shown here.
|
||||
;See also:
|
||||
* the Wikipedia entry: [[wp:Merge_sort| merge sort]]
|
||||
|
||||
|
||||
Note: better performance can be expected if, rather than recursing until <big> length(m) ≤ 1, </big> an insertion sort is used for <big> length(m) </big> smaller than some threshold larger than '''1'''. However, this complicates the example code, so it is not shown here.
|
||||
<br><br>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -1,14 +1,13 @@
|
|||
(defn merge* [left right]
|
||||
(defn merge [left right]
|
||||
(cond (nil? left) right
|
||||
(nil? right) left
|
||||
true (let [[l & *left] left
|
||||
[r & *right] right]
|
||||
(if (<= l r) (cons l (merge* *left right))
|
||||
(cons r (merge* left *right))))))
|
||||
:else (let [[l & *left] left
|
||||
[r & *right] right]
|
||||
(if (<= l r) (cons l (merge *left right))
|
||||
(cons r (merge left *right))))))
|
||||
|
||||
(defn merge-sort [L]
|
||||
(let [[l & *L] L]
|
||||
(if (nil? *L)
|
||||
L
|
||||
(let [[left right] (split-at (/ (count L) 2) L)]
|
||||
(merge* (merge-sort left) (merge-sort 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)))))
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -12,21 +12,19 @@ function merge(left, right, arr) {
|
|||
}
|
||||
}
|
||||
|
||||
function mSort(arr, tmp, len) {
|
||||
function mergeSort(arr) {
|
||||
var len = arr.length;
|
||||
|
||||
if (len === 1) { return; }
|
||||
|
||||
var m = Math.floor(len / 2),
|
||||
tmp_l = tmp.slice(0, m),
|
||||
tmp_r = tmp.slice(m);
|
||||
var mid = Math.floor(len / 2),
|
||||
left = arr.slice(0, mid),
|
||||
right = arr.slice(mid);
|
||||
|
||||
mSort(tmp_l, arr.slice(0, m), m);
|
||||
mSort(tmp_r, arr.slice(m), len - m);
|
||||
merge(tmp_l, tmp_r, arr);
|
||||
}
|
||||
|
||||
function merge_sort(arr) {
|
||||
mSort(arr, arr.slice(), arr.length);
|
||||
mergeSort(left);
|
||||
mergeSort(right);
|
||||
merge(left, right, arr);
|
||||
}
|
||||
|
||||
var arr = [1, 5, 2, 7, 3, 9, 4, 6, 8];
|
||||
merge_sort(arr); // arr will now: 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||
mergeSort(arr); // arr will now: 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||
|
|
|
|||
|
|
@ -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)}")
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -10,8 +10,8 @@ def merge(left, right):
|
|||
result.append(right[right_idx])
|
||||
right_idx += 1
|
||||
|
||||
if left:
|
||||
if left_idx < len(left):
|
||||
result.extend(left[left_idx:])
|
||||
if right:
|
||||
if right_idx < len(right):
|
||||
result.extend(right[right_idx:])
|
||||
return result
|
||||
|
|
|
|||
|
|
@ -1,57 +1,38 @@
|
|||
/*REXX program sorts a (stemmed) array using the merge─sort algorithm.*/
|
||||
call gen@; w=length(#) /*generate an array (@.) of items*/
|
||||
call show@ 'before sort' /*show the before array elements.*/
|
||||
call mergeSort # /*invoke the merge sort for array*/
|
||||
call show@ ' after sort' /*show the after array elements.*/
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────GEN@ subroutine─────────────────────*/
|
||||
gen@: @. = /*assign default value for @ stem*/
|
||||
@.1 = '---The seven deadly sins---' /*pick a favorite.*/
|
||||
@.2 = '==========================='
|
||||
@.3 = 'pride'
|
||||
@.4 = 'avarice'
|
||||
@.5 = 'wrath'
|
||||
@.6 = 'envy'
|
||||
@.7 = 'gluttony'
|
||||
@.8 = 'sloth'
|
||||
@.9 = 'lust'
|
||||
do #=1 while @.#\==''; end; #=#-1 /*find the number of entries in @*/
|
||||
return
|
||||
/*──────────────────────────────────MERGESORT subroutine────────────────*/
|
||||
mergeSort: procedure expose @.; call mergeTo@ 1,arg(1); return
|
||||
/*──────────────────────────────────MERGETO@ subroutine─────────────────*/
|
||||
mergeTo@: procedure expose @. !.; parse arg L,n ; if n==1 then return
|
||||
if n==2 then do; h=L+1 /*handle special case of 2 items.*/
|
||||
if @.L>@.h then do; _=@.h; @.h=@.L; @.L=_; end
|
||||
return
|
||||
end
|
||||
m=n%2 /*cut N in half (integer div.)*/
|
||||
call mergeTo@ L+m,n-m /*divide items to the left ···*/
|
||||
call mergeTo! L,m,1 /* " " " " right ···*/
|
||||
i=1; j=L+m; do k=L while k<j /*whilst items on right···*/
|
||||
if j==L+n | !.i<=@.j then do; @.k=!.i; i=i+1; end
|
||||
else do; @.k=@.j; j=j+1; end
|
||||
end /*k*/
|
||||
return
|
||||
/*──────────────────────────────────MERGETO! subroutine─────────────────*/
|
||||
mergeTo!: procedure expose @. !.; parse arg L,n,_
|
||||
if n==1 then do; !._=@.L; return; end /*handle special case of 1 item. */
|
||||
if n==2 then do /* " " " " 2 items.*/
|
||||
h=L+1; q=1+_
|
||||
if @.L>@.h then do; q=_; _=q+1; end
|
||||
!._=@.L; !.q=@.h
|
||||
return /*done with special case of N=2.*/
|
||||
end
|
||||
m=n%2 /*cut N in half (integer div).*/
|
||||
call mergeTo@ L,m /*divide items to the left ···*/
|
||||
call mergeTo! L+m,n-m,m+_ /* " " " " right ···*/
|
||||
i=L; j=m+_; do k=_ while k<j /*whilst items on left ···*/
|
||||
if j==_+n | @.i<=!.j then do; !.k=@.i; i=i+1; end
|
||||
else do; !.k=!.j; j=j+1; end
|
||||
end /*k*/
|
||||
return
|
||||
/*──────────────────────────────────SHOW@ subroutine────────────────────*/
|
||||
show@: say copies('▒',70); do j=1 for #; pad=left('',10) /*indent.*/
|
||||
say pad 'element' right(j,w) arg(1)':' @.j
|
||||
end /*j*/
|
||||
return
|
||||
/*REXX program sorts a stemmed array (numbers or chars) using the merge─sort algorithm.*/
|
||||
@.=; @.1 = '---The seven deadly sins---'
|
||||
@.2 = '===========================' ; @.6 = "envy"
|
||||
@.3 = 'pride' ; @.7 = "gluttony"
|
||||
@.4 = 'avarice' ; @.8 = "sloth"
|
||||
@.5 = 'wrath' ; @.9 = "lust"
|
||||
do #=1 while @.#\==''; end; #=#-1; w=length(#) /*#≡number of entries in @*/
|
||||
call show@ 'before sort' /*show the "before" array elements. */
|
||||
say copies('▒', 70) /*display a separator line to the term.*/
|
||||
call mergeSort # /*invoke the merge sort for the array*/
|
||||
call show@ ' after sort' /*show the "after" array elements. */
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
mergeSort: procedure expose @.; call mergeTo@ 1,arg(1); return
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
mergeTo@: procedure expose @. !.; parse arg L,n; if n==1 then return; h=L+1
|
||||
if n==2 then do; if @.L>@.h then do; _=@.h; @.h=@.L; @.L=_; end; return; end
|
||||
m=n%2 /* [↑] handle case of two items.*/
|
||||
call mergeTo@ L+m,n-m /*divide items to the left ···*/
|
||||
call mergeTo! L,m,1 /* " " " " right ···*/
|
||||
i=1; j=L+m; do k=L while k<j /*whilst items on right exist ···*/
|
||||
if j==L+n | !.i<=@.j then do; @.k=!.i; i=i+1; end
|
||||
else do; @.k=@.j; j=j+1; end
|
||||
end /*k*/
|
||||
return
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
mergeTo!: procedure expose @. !.; parse arg L,n,T; if n==1 then do; !.T=@.L; return; end
|
||||
if n==2 then do; h=L+1; q=T+1; !.q=@.L; !.T=@.h; return; end
|
||||
m=n%2 /* [↑] handle case of two items.*/
|
||||
call mergeTo@ L,m /*divide items to the left ···*/
|
||||
call mergeTo! L+m,n-m,m+T /* " " " " right ···*/
|
||||
i=L; j=m+T; do k=T while k<j /*whilst items on left exist ···*/
|
||||
if j==T+n | @.i<=!.j then do; !.k=@.i; i=i+1; end
|
||||
else do; !.k=!.j; j=j+1; end
|
||||
end /*k*/
|
||||
return
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
show@: do j=1 for #; say right('element',17) right(j,w) arg(1)":" @.j; end; return
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
fn merge<T: Copy + PartialOrd>(x1: &[T], x2: &[T], y: &mut [T]) {
|
||||
assert_eq!(x1.len() + x2.len(), y.len());
|
||||
let mut i = 0;
|
||||
let mut j = 0;
|
||||
let mut k = 0;
|
||||
while i < x1.len() && j < x2.len() {
|
||||
if x1[i] < x2[j] {
|
||||
y[k] = x1[i];
|
||||
k += 1;
|
||||
i += 1;
|
||||
} else {
|
||||
y[k] = x2[j];
|
||||
k += 1;
|
||||
j += 1;
|
||||
}
|
||||
}
|
||||
if i < x1.len() {
|
||||
y[k..].copy_from_slice(&x1[i..]);
|
||||
}
|
||||
if j < x2.len() {
|
||||
y[k..].copy_from_slice(&x2[j..]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
fn merge_sort_rec<T: Copy + Ord>(x: &mut [T]) {
|
||||
let n = x.len();
|
||||
let m = n / 2;
|
||||
|
||||
if n <= 1 {
|
||||
return;
|
||||
}
|
||||
|
||||
merge_sort_rec(&mut x[0..m]);
|
||||
merge_sort_rec(&mut x[m..n]);
|
||||
|
||||
let mut y: Vec<T> = x.to_vec();
|
||||
|
||||
merge(&x[0..m], &x[m..n], &mut y[..]);
|
||||
|
||||
x.copy_from_slice(&y);
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
fn merge_sort<T: Copy + PartialOrd>(x: &mut [T]) {
|
||||
let n = x.len();
|
||||
let mut y = x.to_vec();
|
||||
let mut len = 1;
|
||||
while len < n {
|
||||
let mut i = 0;
|
||||
while i < n {
|
||||
if i + len >= n {
|
||||
y[i..].copy_from_slice(&x[i..]);
|
||||
} else if i + 2 * len > n {
|
||||
merge(&x[i..i+len], &x[i+len..], &mut y[i..]);
|
||||
} else {
|
||||
merge(&x[i..i+len], &x[i+len..i+2*len], &mut y[i..i+2*len]);
|
||||
}
|
||||
i += 2 * len;
|
||||
}
|
||||
len *= 2;
|
||||
if len >= n {
|
||||
x.copy_from_slice(&y);
|
||||
return;
|
||||
}
|
||||
i = 0;
|
||||
while i < n {
|
||||
if i + len >= n {
|
||||
x[i..].copy_from_slice(&y[i..]);
|
||||
} else if i + 2 * len > n {
|
||||
merge(&y[i..i+len], &y[i+len..], &mut x[i..]);
|
||||
} else {
|
||||
merge(&y[i..i+len], &y[i+len..i+2*len], &mut x[i..i+2*len]);
|
||||
}
|
||||
i += 2 * len;
|
||||
}
|
||||
len *= 2;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue