Skip to content

Commit

Permalink
feat: 优化归并排序性能
Browse files Browse the repository at this point in the history
  • Loading branch information
originalix committed Feb 3, 2021
1 parent 1750ea2 commit daae75e
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 27 deletions.
17 changes: 17 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/src/algs4/sort/merge-sort.ts",
"outFiles": ["${workspaceFolder}/dist/**/*.js"]
}
]
}


6 changes: 3 additions & 3 deletions src/algs4/sort/base-sort.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ abstract class BaseSort<T> {
this.array = array
}

abstract sort(): void
abstract sort(array?: T[]): void

protected less(v: T, w: T): boolean {
return v < w
Expand All @@ -30,8 +30,8 @@ abstract class BaseSort<T> {
return true
}

main() {
this.sort()
main(passArray?: boolean) {
passArray ? this.sort(this.array) : this.sort()
assert(this.isSorted(), '数组排序错误')
this.show()
}
Expand Down
45 changes: 22 additions & 23 deletions src/algs4/sort/merge-sort.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,41 @@ import { StdIn, StopWatch } from 'utils'
import { SortMockFile } from '@/constants'

class MergeSort<T> extends BaseSort<T> {
sort() {
this.array = this._sort(this.array)
private aux: T[] // 归并所需的辅助数组

sort(a: T[]) {
this.aux = []
this._sort(a, 0, a.length - 1)
}

private _sort(array: T[]): T[] {
if (array.length <= 1) return array
const middle = Math.floor(array.length / 2)
const left = array.slice(0, middle)
const right = array.slice(middle)
return this.merge(this._sort(left), this._sort(right))
private _sort(a: T[], lo: number, hi: number) {
if (hi <= lo) return
const mid = lo + Math.floor((hi - lo) / 2)
this._sort(a, lo, mid) // 将左半边排序
this._sort(a, mid + 1, hi) // 将右半边排序
this.merge(a, lo, mid, hi) // 归并结果
}

private merge(left: T[], right: T[]): T[] {
const res: T[] = []
while (left.length && right.length) {
if (left[0] < right[0]) {
res.push(left.shift())
} else {
res.push(right.shift())
}
}
while (left.length) {
res.push(left.shift())
private merge(a: T[], lo: number, mid: number, hi: number) {
// 将a[lo..mid] 和 a[mid+1..hi] 归并
let i = lo; let j = mid + 1
for (let k = lo; k <= hi; k++) { // 将a[lo..mid] 复制到 aux[lo..hi]
this.aux[k] = a[k]
}
while (right.length) {
res.push(right.shift())
for (let k = lo; k <= hi; k++) { // 归并回到 a[lo..hi]
if (i > mid) a[k] = this.aux[j++]
else if (j > hi) a[k] = this.aux[i++]
else if (this.less(this.aux[j], this.aux[i])) a[k] = this.aux[j++]
else a[k] = this.aux[i++]
}
return res
}
}

async function main() {
const data = await StdIn.readInt(SortMockFile)
const stopWatch = new StopWatch()
const merge = new MergeSort<number>(data)
merge.main()
merge.main(true)
stopWatch.elapseTime()
}

Expand Down
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"@/*": ["*"],
"utils": ["utils"],
"mock": ["mock"]
}
},
"sourceMap": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
Expand Down
1 change: 1 addition & 0 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ module.exports = {
},
extensions: ['.ts', '.js']
},
devtool: 'source-map',
devServer: {
contentBase: './dist'
},
Expand Down

0 comments on commit daae75e

Please sign in to comment.