Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a5e3b07

Browse files
committed
docs: add algorithm
1 parent 5cfbd76 commit a5e3b07

25 files changed

+1061
-12
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module.exports = {
2+
env: {
3+
browser: true,
4+
es6: true,
5+
},
6+
extends: [
7+
'airbnb-base',
8+
],
9+
globals: {
10+
Atomics: 'readonly',
11+
SharedArrayBuffer: 'readonly',
12+
},
13+
parserOptions: {
14+
ecmaVersion: 2018,
15+
sourceType: 'module',
16+
},
17+
rules: {
18+
},
19+
};

算法与数据结构学习/README.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22

33
## 数据结构
44

5-
- [链表](https://github.com/Mayandev/javascript_algorithm/blob/master/%E7%AE%97%E6%B3%95%E4%B8%8E%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%AD%A6%E4%B9%A0/data-structures/linked-list)
6-
7-
- [双向链表](https://github.com/Mayandev/javascript_algorithm/blob/master/%E7%AE%97%E6%B3%95%E4%B8%8E%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%AD%A6%E4%B9%A0/data-structures/doubly-linked-list)
8-
9-
- [队列](https://github.com/Mayandev/javascript_algorithm/blob/master/%E7%AE%97%E6%B3%95%E4%B8%8E%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%AD%A6%E4%B9%A0/data-structures/queue)
5+
- [链表](data-structures/linked-list)
6+
- [双向链表](data-structures/doubly-linked-list)
7+
- [队列](data-structures/queue)
8+
- [堆栈](data-structures/stack)
9+
- [哈希表](data-structures/hash-table)
10+
- [](data-structures/heap)
11+
- [有限队列](data-structures/priority-queue)
1012

1113
## 算法
1214

1315
### 排序
1416

15-
- [归并排序](https://github.com/Mayandev/javascript_algorithm/blob/master/%E7%AE%97%E6%B3%95%E4%B8%8E%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%AD%A6%E4%B9%A0/algorithms/sort/merge-sort.js)
17+
- [归并排序](algorithms/sort/merge-sort)
18+
- [堆排序](algorithms/sort/heap-sort)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
export const sortedArr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
2+
export const reverseArr = [20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1];
3+
export const notSortedArr = [15, 8, 5, 12, 10, 1, 16, 9, 11, 7, 20, 3, 2, 6, 17, 18, 4, 13, 14, 19];
4+
export const equalArr = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
5+
export const negativeArr = [-1, 0, 5, -10, 20, 13, -7, 3, 2, -3];
6+
export const negativeArrSorted = [-10, -7, -3, -1, 0, 2, 3, 5, 13, 20];
7+
8+
export class SortTester {
9+
static testSort(SortingClass) {
10+
const sorter = new SortingClass();
11+
12+
expect(sorter.sort([])).toEqual([]);
13+
expect(sorter.sort([1])).toEqual([1]);
14+
expect(sorter.sort([1, 2])).toEqual([1, 2]);
15+
expect(sorter.sort([2, 1])).toEqual([1, 2]);
16+
expect(sorter.sort([3, 4, 2, 1, 0, 0, 4, 3, 4, 2])).toEqual([0, 0, 1, 2, 2, 3, 3, 4, 4, 4]);
17+
expect(sorter.sort(sortedArr)).toEqual(sortedArr);
18+
expect(sorter.sort(reverseArr)).toEqual(sortedArr);
19+
expect(sorter.sort(notSortedArr)).toEqual(sortedArr);
20+
expect(sorter.sort(equalArr)).toEqual(equalArr);
21+
}
22+
23+
static testNegativeNumbersSort(SortingClass) {
24+
const sorter = new SortingClass();
25+
expect(sorter.sort(negativeArr)).toEqual(negativeArrSorted);
26+
}
27+
28+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import MinHeap from '../../../data-structures/heap/MinHeap'
2+
3+
export default class HeapSort {
4+
sort (originalArray) {
5+
const sortedArray = [];
6+
7+
const minHeap = new MinHeap();
8+
9+
originalArray.forEach(element => {
10+
minHeap.add(element)
11+
});
12+
13+
while (!minHeap.isEmpty()) {
14+
const nextMinElement = minHeap.poll();
15+
16+
sortedArray.push(nextMinElement);
17+
}
18+
return sortedArray;
19+
}
20+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Heap Sort
2+
3+
Heapsort是一种基于比较的排序算法。堆排序可以认为是一种改进的选择排序:类似于该算法,它将输入分为排序和未排序的区域,并反复进行通过提取最大的区域来缩小未分类区域元素并将其移至已排序的区域。改进方法包括使用堆数据结构而不是线性时间搜索来找到最大值。
4+
5+
![Algorithm Visualization](https://upload.wikimedia.org/wikipedia/commons/1/1b/Sorting_heapsort_anim.gif)
6+
7+
![Algorithm Visualization](https://upload.wikimedia.org/wikipedia/commons/4/4d/Heapsort-example.gif)
8+
9+
## Complexity
10+
11+
| 名称 | 最优 | 平均 | 最差 | 空间 | 稳定 | Comments |
12+
| --------------------- | :-------------: | :-----------------: | :-----------------: | :-------: | :-------: | :-------- |
13+
| **Heap sort** | n log(n) | n log(n) | n log(n) | 1 | No | |
14+
15+
## References
16+
17+
[Wikipedia](https://en.wikipedia.org/wiki/Heapsort)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import HeapSort from '../HeapSort';
2+
import {
3+
equalArr,
4+
notSortedArr,
5+
reverseArr,
6+
sortedArr,
7+
SortTester,
8+
} from '../../SortTester';
9+
10+
describe('HeapSort', () => {
11+
it('should sort array', () => {
12+
SortTester.testSort(HeapSort);
13+
});
14+
15+
it('should sort negative numbers', () => {
16+
SortTester.testNegativeNumbersSort(HeapSort);
17+
});
18+
19+
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Merge Sort
2+
3+
在计算机科学中,合并排序(通常也拼写为mergesort)是一种高效的通用功能,基于比较的排序算法。 大多数实施产生稳定的排序,这意味着执行保留排序后相等元素的输入顺序输出。 Mergesort是一种分而治之的算法,由约翰·冯·诺伊曼(John von Neumann)于1945年发明。
4+
5+
合并排序的示例。 首先将列表分为最小单位(1个元素),然后比较每个元素与相邻列表进行排序和合并两个相邻的列表。 最后将所有元素排序并合并。
6+
7+
![合并排序]https://upload.wikimedia.org/wikipedia/commons/c/cc/Merge-sort-example-300px.gif)
8+
9+
递归合并排序算法,用于对7个数组进行排序整数值。 这些是人类将要采取的步骤模拟合并排序(自上而下)。
10+
11+
12+
![Merge Sort](https://upload.wikimedia.org/wikipedia/commons/e/e6/Merge_sort_algorithm_diagram.svg)
13+
14+
## Complexity
15+
16+
| 名称 | 最优 | 平均 | 最差 | 空间 | 稳定 | 评论 |
17+
| --------------------- | :-------------: | :-----------------: | :-----------------: | :-------: | :-------: | :-------- |
18+
| **归并排序** | n log(n) | n log(n) | n log(n) | n | Yes | |
19+
20+
## References
21+
22+
- [Wikipedia](https://en.wikipedia.org/wiki/Merge_sort)
23+
- [YouTube](https://www.youtube.com/watch?v=KF2j-9iSf4Q&index=27&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8)

算法与数据结构学习/data-structures/hash-table/HashTable.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ export default class HashTable {
2626
0,
2727
);
2828

29+
console.log(hash);
30+
31+
2932

3033
// 减少哈希数,使其适合哈希表的大小。
3134
return hash % this.buckets.length;
@@ -34,7 +37,6 @@ export default class HashTable {
3437
// 插入函数
3538
set(key, value) {
3639
const keyHash = this.hash(key);
37-
console.log(key, value);
3840
this.keys[key] = keyHash;
3941
const bucketLinkedList = this.buckets[keyHash];
4042
const node = bucketLinkedList.find({callback: nodeValue => nodeValue.key === key})
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# 哈希表
2+
3+
在计算中, 一个 **哈希表(hash table 或hash map)** 是一种实现 *关联数组(associative array)*
4+
的抽象数据;类型, 该结构可以将 *键映射到值*
5+
6+
哈希表使用 *哈希函数/散列函数* 来计算一个值在数组或桶(buckets)中或槽(slots)中对应的索引,可使用该索引找到所需的值。
7+
8+
理想情况下,散列函数将为每个键分配给一个唯一的桶(bucket),但是大多数哈希表设计采用不完美的散列函数,这可能会导致"哈希冲突(hash collisions)",也就是散列函数为多个键(key)生成了相同的索引,这种碰撞必须
9+
以某种方式进行处理。
10+
11+
12+
![Hash Table](https://upload.wikimedia.org/wikipedia/commons/7/7d/Hash_table_3_1_1_0_1_0_0_SP.svg)
13+
14+
通过单独的链接解决哈希冲突
15+
16+
![Hash Collision](https://upload.wikimedia.org/wikipedia/commons/d/d0/Hash_table_5_0_1_1_1_1_1_LL.svg)
17+
18+
## 参考
19+
20+
- [Wikipedia](https://en.wikipedia.org/wiki/Hash_table)
21+
- [YouTube](https://www.youtube.com/watch?v=shs0KM3wKv8&index=4&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8)

算法与数据结构学习/data-structures/hash-table/Test.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ import HashTable from './HashTable';
22

33
let hashTable = new HashTable();
44

5-
hashTable.set('a', 'aaaaaa')
6-
hashTable.set('b', 'bbbbbb')
7-
hashTable.set('c', 'cccccc')
8-
hashTable.set('d', 'dddddd')
5+
hashTable.set('a', 'sky-old');
6+
hashTable.set('a', 'sky');
7+
hashTable.set('b', 'sea');
8+
hashTable.set('c', 'earth');
9+
hashTable.set('d', 'ocean');
910

10-
hashTable.get('c')
11+
hashTable.buckets[1].toString();
1112
console.log(hashTable.getKeys())
1213
console.log(hashTable.has);
1314

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import HashTable from '../HashTable';
2+
3+
describe('HashTable', () => {
4+
it('should create hash table of certain size', () => {
5+
const defaultHashTable = new HashTable();
6+
expect(defaultHashTable.buckets.length).toBe(32);
7+
8+
const biggerHashTable = new HashTable(64);
9+
expect(biggerHashTable.buckets.length).toBe(64);
10+
});
11+
12+
it('should generate proper hash for specified keys', () => {
13+
const hashTable = new HashTable();
14+
15+
expect(hashTable.hash('a')).toBe(1);
16+
expect(hashTable.hash('b')).toBe(2);
17+
expect(hashTable.hash('abc')).toBe(6);
18+
});
19+
20+
it('should set, read and delete data with collisions', () => {
21+
const hashTable = new HashTable(3);
22+
23+
expect(hashTable.hash('a')).toBe(1);
24+
expect(hashTable.hash('b')).toBe(2);
25+
expect(hashTable.hash('c')).toBe(0);
26+
expect(hashTable.hash('d')).toBe(1);
27+
28+
hashTable.set('a', 'sky-old');
29+
hashTable.set('a', 'sky');
30+
hashTable.set('b', 'sea');
31+
hashTable.set('c', 'earth');
32+
hashTable.set('d', 'ocean');
33+
34+
expect(hashTable.has('x')).toBe(false);
35+
expect(hashTable.has('b')).toBe(true);
36+
expect(hashTable.has('c')).toBe(true);
37+
38+
const stringifier = value => `${value.key}:${value.value}`;
39+
40+
expect(hashTable.buckets[0].toString(stringifier)).toBe('c:earth');
41+
expect(hashTable.buckets[1].toString(stringifier)).toBe('a:sky,d:ocean');
42+
expect(hashTable.buckets[2].toString(stringifier)).toBe('b:sea');
43+
44+
expect(hashTable.get('a')).toBe('sky');
45+
expect(hashTable.get('d')).toBe('ocean');
46+
expect(hashTable.get('x')).not.toBeDefined();
47+
48+
hashTable.delete('a');
49+
50+
expect(hashTable.delete('not-existing')).toBeNull();
51+
52+
expect(hashTable.get('a')).not.toBeDefined();
53+
expect(hashTable.get('d')).toBe('ocean');
54+
55+
hashTable.set('d', 'ocean-new');
56+
expect(hashTable.get('d')).toBe('ocean-new');
57+
});
58+
59+
it('should be possible to add objects to hash table', () => {
60+
const hashTable = new HashTable();
61+
62+
hashTable.set('objectKey', { prop1: 'a', prop2: 'b' });
63+
64+
const object = hashTable.get('objectKey');
65+
expect(object).toBeDefined();
66+
expect(object.prop1).toBe('a');
67+
expect(object.prop2).toBe('b');
68+
});
69+
70+
it('should track actual keys', () => {
71+
const hashTable = new HashTable(3);
72+
73+
hashTable.set('a', 'sky-old');
74+
hashTable.set('a', 'sky');
75+
hashTable.set('b', 'sea');
76+
hashTable.set('c', 'earth');
77+
hashTable.set('d', 'ocean');
78+
79+
expect(hashTable.getKeys()).toEqual(['a', 'b', 'c', 'd']);
80+
expect(hashTable.has('a')).toBe(true);
81+
expect(hashTable.has('x')).toBe(false);
82+
83+
hashTable.delete('a');
84+
85+
expect(hashTable.has('a')).toBe(false);
86+
expect(hashTable.has('b')).toBe(true);
87+
expect(hashTable.has('x')).toBe(false);
88+
});
89+
});

0 commit comments

Comments
 (0)