Another update from ingydotnet^djgoku
This commit is contained in:
parent
91df62d461
commit
948b86eafa
7604 changed files with 108452 additions and 22726 deletions
|
|
@ -1,105 +1,36 @@
|
|||
Function Merge-Array( [Object[]] $lhs, [Object[]] $rhs )
|
||||
function MergeSort([object[]] $SortInput)
|
||||
{
|
||||
$result = @()
|
||||
$lhsl = $lhs.length
|
||||
$rhsl = $rhs.length
|
||||
if( $lhsl -gt 0 )
|
||||
# The base case exits for minimal lists that are sorted by definition
|
||||
if ($SortInput.Length -le 1) {return $SortInput}
|
||||
|
||||
# Divide and conquer
|
||||
[int] $midPoint = $SortInput.Length/2
|
||||
# The @() operators ensure a single result remains typed as an array
|
||||
[object[]] $left = @(MergeSort @($SortInput[0..($midPoint-1)]))
|
||||
[object[]] $right = @(MergeSort @($SortInput[$midPoint..($SortInput.Length-1)]))
|
||||
|
||||
# Merge
|
||||
[object[]] $result = @()
|
||||
while (($left.Length -gt 0) -and ($right.Length -gt 0))
|
||||
{
|
||||
if( $rhsl -gt 0 )
|
||||
if ($left[0] -lt $right[0])
|
||||
{
|
||||
$i = 0
|
||||
for( $j = 0; ( $i -lt $lhsl ) -and ( $j -lt $rhsl ); )
|
||||
{
|
||||
if( $lhs[ $i ] -le $rhs[ $j ] )
|
||||
{
|
||||
$result += $lhs[ $i ]
|
||||
[void] ( $i++ )
|
||||
} else {
|
||||
$result += $rhs[ $j ]
|
||||
[void] ( $j++ )
|
||||
}
|
||||
}
|
||||
if( $i -lt $lhsl )
|
||||
{
|
||||
$result += $lhs[ $i..( $lhsl - 1 ) ]
|
||||
}
|
||||
if( $j -lt $rhsl )
|
||||
{
|
||||
$result += $rhs[ $j..( $rhsl - 1 ) ]
|
||||
}
|
||||
} else {
|
||||
for( $i = 0; $i -lt $lhsl; $i++ )
|
||||
{
|
||||
if( $rhs -le $lhs[ $i ] )
|
||||
{
|
||||
$result += $rhs
|
||||
break
|
||||
}
|
||||
$result += $lhs[ $i ]
|
||||
}
|
||||
if( $i -lt $lhsl )
|
||||
{
|
||||
$result += $lhs[ $i..( $lhsl - 1 ) ]
|
||||
}
|
||||
$result += $left[0]
|
||||
# Use an if/else rather than accessing the array range as $array[1..0]
|
||||
if ($left.Length -gt 1){$left = $left[1..$($left.Length-1)]}
|
||||
else {$left = @()}
|
||||
}
|
||||
} else {
|
||||
if( $rhsl -gt 0 )
|
||||
else
|
||||
{
|
||||
for( $i = 0; $i -lt $rhsl; $i++ )
|
||||
{
|
||||
if( $lhs -le $rhs[ $i ] )
|
||||
{
|
||||
$result += $lhs
|
||||
break
|
||||
}
|
||||
$result += $rhs[ $i ]
|
||||
}
|
||||
if( $i -lt $rhsl )
|
||||
{
|
||||
$result += $rhs[ $i..( $rhsl - 1 ) ]
|
||||
}
|
||||
} else {
|
||||
if( $lhs -lt $rhs )
|
||||
{
|
||||
$result += $lhs
|
||||
$result += $rhs
|
||||
} else {
|
||||
$result += $rhs
|
||||
$result += $lhs
|
||||
}
|
||||
$result += $right[0]
|
||||
# Without the if/else, $array[1..0] would return the whole array when $array.Length == 1
|
||||
if ($right.Length -gt 1){$right = $right[1..$($right.Length-1)]}
|
||||
else {$right = @()}
|
||||
}
|
||||
}
|
||||
$result
|
||||
|
||||
# If we get here, either $left or $right is an empty array (or both are empty!). Since the
|
||||
# rest of the unmerged array is already sorted, we can simply string together what we have.
|
||||
# This line outputs the concatenated result. An explicit 'return' statement is not needed.
|
||||
$result + $left + $right
|
||||
}
|
||||
|
||||
Function MergeSort( [Object[]] $data )
|
||||
{
|
||||
$datal = $data.length - 1
|
||||
if( $datal -gt 0 )
|
||||
{
|
||||
$middle = [Math]::Floor( $datal / 2 )
|
||||
$left = @()
|
||||
$left += MergeSort $data[ 0..$middle ]
|
||||
$right = @()
|
||||
$right += MergeSort $data[ ( $middle + 1 )..$datal ]
|
||||
if( $left[ -1 ] -le $right[ 0 ] )
|
||||
{
|
||||
$result = @()
|
||||
$result += $left
|
||||
$result += $right
|
||||
$result
|
||||
} elseif( $right[ -1 ] -le $left[ 0 ] )
|
||||
{
|
||||
$result = @()
|
||||
$result += $right
|
||||
$result += $left
|
||||
$result
|
||||
} else {
|
||||
Merge-Array $left $right
|
||||
}
|
||||
} else {
|
||||
$data
|
||||
}
|
||||
}
|
||||
|
||||
$l = 100; MergeSort ( 1..$l | ForEach-Object { $Rand = New-Object Random }{ $Rand.Next( 0, $l - 1 ) } )
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue