add bucket sort and binary search

This commit is contained in:
xuzhiwei 2019-06-08 18:01:58 +09:00
parent e714cc2c9f
commit de13b81887
5 changed files with 195 additions and 12 deletions

View File

@ -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)

View File

@ -3,24 +3,19 @@
* O1使广
* O(nlg(n))
*/
interface ArraySort {
sort(array: number[]): void
}
class QuickSort implements ArraySort {
sort(array: number[]): void {
export class QuickSort {
static sort(array: number[]): void {
this.sortInternally(array, 0, array.length - 1)
}
private sortInternally(array: number[], p: number, r: number) {
private static sortInternally(array: number[], p: number, r: number) {
if (p >= r) return
// 获取分界点
const q: number = this.partition(array, p, r)
this.sortInternally(array, p, q - 1)
this.sortInternally(array, q + 1, r)
}
private partition(array: number[], p: number, r: number): number {
private static partition(array: number[], p: number, r: number): number {
/**
* pivotpivot的放在左边pivot的在右边
* index一定是值在中间的下标
@ -39,7 +34,7 @@ class QuickSort implements ArraySort {
return index - 1
}
private swap(array: number[], p: number, q: number) {
private static swap(array: number[], p: number, q: number) {
const temp = array[p]
array[p] = array[q]
array[q] = temp
@ -47,6 +42,5 @@ class QuickSort implements ArraySort {
}
const testSort = [1, 3, 2, 3, 10, 9, 7, 6, 0, -12]
const quickSort: ArraySort = new QuickSort()
quickSort.sort(testSort)
QuickSort.sort(testSort)
console.log(testSort)

View File

@ -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)

View File

@ -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)

View File

@ -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))