forked from wangzheng0822/algo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
195 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/** | ||
* 归并排序 | ||
* 稳定排序,稳定的O(nlgn)时间复杂度 | ||
* O(n)的空间复杂度 | ||
* 在小规模数据排序中很常用 | ||
*/ | ||
class MergeSort { | ||
public static mergeSort(array: number[]) { | ||
if (!array || !array.length) return | ||
const length = array.length | ||
this.mergeSortInternally(array, 0, length - 1) | ||
} | ||
|
||
static mergeSortInternally(array: number[], p: number, r: number) { | ||
if (p >= r) return | ||
// 严格按照中间值作切分点 | ||
// js中除法需要做取整操作,不然结果有可能是小数 | ||
const q = Math.floor(p + (r - p) / 2) | ||
this.mergeSortInternally(array, p, q) | ||
this.mergeSortInternally(array, q + 1, r) | ||
this.mergeArray(array, p, q, r) | ||
} | ||
|
||
private static mergeArray(a: number[], p: number, q: number, r: number) { | ||
let i = p | ||
let j = q + 1 | ||
let k = 0 | ||
// 定义一个临时数组来存放排序的值 | ||
const tmp: number[] = [] | ||
while (i <= q && j <= r) { | ||
if (a[i] <= a[j]) { | ||
tmp[k++] = a[i++] | ||
} else { | ||
tmp[k++] = a[j++] | ||
} | ||
} | ||
// 判断哪个子数组中有剩余的数据 | ||
let start = i | ||
let end = q | ||
if (j <= r) { | ||
start = j | ||
end = r | ||
} | ||
// 将剩余的数据拷贝到临时数组tmp | ||
while (start <= end) { | ||
tmp[k++] = a[start++] | ||
} | ||
|
||
// 将tmp中的数组拷贝回a[p...r] | ||
for (i = 0; i <= r - p; i++) { | ||
a[p + i] = tmp[i] | ||
} | ||
} | ||
} | ||
|
||
const test4 = [1, 3, 2, 3, 10, 9, 7, 6, 0, 12] | ||
MergeSort.mergeSort(test4) | ||
console.log(test4) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/** | ||
* 桶排序对数据的要求比较高 | ||
* 首先要知道数据的范围 | ||
* 然后根据范围将数据分到小范围的桶中 | ||
* 每个桶采用快速排序 | ||
* 当桶的数量接近数据量大小的时候,时间复杂度为O(n) | ||
*/ | ||
import { QuickSort } from '../12_sorts/quickSort' | ||
|
||
class BucketSort { | ||
static sort(array: number[], bucketSize: number = 5) { | ||
const length = array.length | ||
if (length === 0) return array | ||
// 首先要确定数据的范围 | ||
let min = array[0] | ||
let max = array[0] | ||
for (let i = 0; i < length; i++) { | ||
if (array[i] < min) { | ||
min = array[i] | ||
} else if (array[i] > max) { | ||
max = array[i] | ||
} | ||
} | ||
|
||
// 初始化桶,确定桶的数量 | ||
// 因为不能保证正好被整除,需要+1 存放剩余的元素 | ||
const bucketCount = Math.floor((max - min) / bucketSize) + 1 | ||
// 桶是个二维数组 | ||
const buckets = new Array(bucketCount) | ||
for (let i = 0; i < bucketCount; i++) { | ||
buckets[i] = [] | ||
} | ||
|
||
// 利用映射函数将数据分配到各个桶中 | ||
// 这个时间复杂度为O(n) | ||
for (let i = 0; i < length; i++) { | ||
buckets[Math.floor((array[i]-min) / bucketSize)].push(array[i]) | ||
} | ||
array.length = 0 // 返回数组 | ||
for (let i = 0; i < bucketCount; i++) { | ||
// 每个桶里根据具体情况排序,使用插入排序或者快速排序等等 | ||
QuickSort.sort(buckets[i]) | ||
for (let j = 0; j < buckets[i].length; j++) { | ||
array.push(buckets[i][j]); | ||
} | ||
} | ||
} | ||
} | ||
|
||
const bucketTest = [1, 3, 2, 3, 10, 9, 7, 6, 0, -12] | ||
BucketSort.sort(bucketTest) | ||
console.log(bucketTest) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/** | ||
* 计数排序 | ||
* 也是线性时间复杂度,和桶排序非常类似 | ||
* 适用于值范围较小的大数据排序 | ||
* 注意值范围需要不小于0,不然需要将数据预处理 | ||
* 并非原地排序 | ||
*/ | ||
class CountingSort { | ||
static sort(array: number[]) { | ||
const length = array.length | ||
|
||
// 找到这个数组的最大值 | ||
let max = array[0] | ||
array.forEach((item) => { | ||
if (item > max) { | ||
max = item | ||
} | ||
}) | ||
|
||
// 初始化值范围数组 | ||
const countArray = new Array(max + 1).fill(0, 0, max + 1) | ||
// 先计算每个元素的出现个数 | ||
for (let i = 0; i < length; i++) { | ||
countArray[array[i]] = countArray[array[i]] + 1 | ||
} | ||
// 计算元素的累计出现个数 | ||
for (let i = 1; i <= max; i++) { | ||
countArray[i] = countArray[i - 1] + countArray[i] | ||
} | ||
|
||
// 接下来开始计数排序了 | ||
// 空间还是要申请 | ||
const sortedArray = [] | ||
// 倒序遍历能够达到稳定排序的作用 | ||
for (let i = length - 1; i >= 0; i--) { | ||
// -1是为了填补sortedArray在0的位置,因为countArray在0的位置中一定么有值 | ||
const index = countArray[array[i]] - 1 | ||
sortedArray[index] = array[i] | ||
countArray[array[i]]-- | ||
} | ||
for (let i = 0; i < length; i++) { | ||
array[i] = sortedArray[i] | ||
} | ||
} | ||
} | ||
|
||
|
||
const testSort2 = [1, 3, 2, 3, 10, 9, 7, 6, 0] | ||
CountingSort.sort(testSort2) | ||
console.log(testSort2) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/** | ||
* 二分查找适合于连续内存的数组查找 | ||
* 并且是已经排好序的数组 | ||
* 时间复杂度只有log(n) | ||
*/ | ||
class BinarySearch { | ||
static bSearch(array: number[], target: number) { | ||
if (!array || array.length === 0) return -1 | ||
const length = array.length | ||
let low = 0 | ||
let high = length - 1 | ||
while (low <= high) { | ||
// 一定是整数,这边的移位运算优先级低于+,-运算符,需要加括号 | ||
const mid = low + ((high - low) >> 1) | ||
if (array[mid] === target) { | ||
return mid | ||
} else if (array[mid] > target) { | ||
high = mid - 1 | ||
} else { | ||
low = mid + 1 | ||
} | ||
} | ||
return -1 | ||
} | ||
} | ||
|
||
const testBinarySearch = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] | ||
console.log(BinarySearch.bSearch(testBinarySearch, 10)) |