File tree 7 files changed +173
-35
lines changed
7 files changed +173
-35
lines changed Original file line number Diff line number Diff line change 1
- function ListNode ( val ) {
2
- this . val = val ;
3
- this . next = null ;
4
- }
5
1
6
- const a = new ListNode ( 1 )
7
- const b = new ListNode ( 2 )
8
- const c = new ListNode ( 4 )
9
- a . next = b
10
- b . next = c
11
-
12
- c . next = a ;
13
-
14
- console . log ( isCircularLinkList ( a ) )
15
-
16
- const d = new ListNode ( 1 )
17
- const e = new ListNode ( 3 )
18
- const f = new ListNode ( 4 )
19
- d . next = e
20
- e . next = f
21
-
22
- function bianli ( root , vals = [ ] ) {
23
- while ( root && root !== null ) {
24
- vals . push ( root . val )
25
- root = root . next
26
- }
27
- return vals
28
- }
29
- // bianli(a)
30
- // bianli(d)
31
-
32
-
33
- // console.log(bianli(mergeTwoLists3(a, d)))
34
-
35
- import './链表/myLinkList.js'
36
- import { isCircularLinkList } from './utils/linkList.js' ;
Original file line number Diff line number Diff line change
1
+ var LRUCache = function ( capacity ) {
2
+ this . keys = [ ] // 存放key的活跃度
3
+ this . cache = Object . create ( null ) // 缓存对象
4
+ this . capacity = capacity // 缓存长度
5
+ } ;
6
+
7
+ LRUCache . prototype . get = function ( key ) {
8
+ if ( this . cache [ key ] ) {
9
+ // 调整位置
10
+ remove ( this . keys , key )
11
+ this . keys . push ( key )
12
+ return this . cache [ key ]
13
+ }
14
+ return - 1
15
+ } ;
16
+
17
+ LRUCache . prototype . put = function ( key , value ) {
18
+ if ( this . cache [ key ] ) {
19
+ // 存在即更新
20
+ this . cache [ key ] = value
21
+ remove ( this . keys , key )
22
+ this . keys . push ( key )
23
+ } else {
24
+ // 不存在即加入
25
+ this . keys . push ( key )
26
+ this . cache [ key ] = value
27
+ // 判断缓存是否已超过最大值
28
+ if ( this . keys . length > this . capacity ) {
29
+ removeCache ( this . cache , this . keys , this . keys [ 0 ] )
30
+ }
31
+ }
32
+ } ;
33
+
34
+ // 移除 key
35
+ function remove ( arr , key ) {
36
+ if ( arr . length ) {
37
+ const index = arr . indexOf ( key )
38
+ if ( index > - 1 ) {
39
+ return arr . splice ( index , 1 )
40
+ }
41
+ }
42
+ }
43
+
44
+ // 移除缓存中 key
45
+ function removeCache ( cache , keys , key ) {
46
+ cache [ key ] = null
47
+ remove ( keys , key )
48
+ }
49
+
50
+ var cache = new LRUCache ( 2 /* 缓存容量 */ ) ;
51
+
52
+ cache . put ( 1 , 1 ) ;
53
+ cache . put ( 2 , 2 ) ;
54
+ cache . get ( 1 ) ; // 返回 1
55
+ cache . put ( 3 , 3 ) ; // 该操作会使得密钥 2 作废
56
+ cache . get ( 2 ) ; // 返回 -1 (未找到)
57
+ cache . put ( 4 , 4 ) ; // 该操作会使得密钥 1 作废
58
+ cache . get ( 1 ) ; // 返回 -1 (未找到)
59
+ cache . get ( 3 ) ; // 返回 3
60
+ cache . get ( 4 ) ; // 返回 4
Original file line number Diff line number Diff line change
1
+ export const Stack = ( function ( ) {
2
+ const items = new WeakMap ( ) ;
3
+ class Stack {
4
+ constructor ( ) {
5
+ items . set ( this , [ ] ) ;
6
+ }
7
+ getItems ( ) {
8
+ let s = items . get ( this ) ;
9
+ return s ;
10
+ }
11
+ push ( element ) {
12
+ this . getItems ( ) . push ( element ) ;
13
+ }
14
+ pop ( ) {
15
+ return this . getItems ( ) . pop ( ) ;
16
+ }
17
+ peek ( ) {
18
+ return this . getItems ( ) [ this . getItems . length - 1 ] ;
19
+ }
20
+ isEmpty ( ) {
21
+ return this . getItems ( ) . length == 0 ;
22
+ }
23
+ size ( ) {
24
+ return this . getItems ( ) . length ;
25
+ }
26
+ clear ( ) {
27
+ this . getItems ( ) = [ ] ;
28
+ }
29
+ }
30
+ return Stack ;
31
+ } ) ( ) ;
Original file line number Diff line number Diff line change
1
+ # 数据结构之栈
2
+ 1、栈 是一种遵循 后进先出(LIFO) 原则的有序集合。新添加和待删除的数据都保存在栈的同一端栈顶,另一端就是栈底。新元素靠近栈顶,旧元素靠近栈底。
3
+ 栈由编译器自动分配释放。栈使用一级缓存。调用时处于存储空间,调用完毕自动释放。
4
+ 举个栗子:乒乓球盒子/搭建积木
5
+ ![ ] ( images/2021-05-29-13-09-42.png )
6
+
7
+ 2.2 基本数据结构的存储(存储栈)
8
+ javaScript中,数据类型分为基本数据类型和引用数据类型,基本数据类型包含:string、number、boolean、undefined、null、symbol、bigint这几种。在内存中这几种数据类型存储在栈空间,我们按值访问。原型类型都存储在栈内存中,是大小固定并且有序的。
9
+ ![ ] ( images/2021-05-29-13-11-13.png )
10
+
11
+ 2.3 执行栈(函数调用栈)
12
+ 我们知道了基本数据结构的存储之后,我们再来看看JavaScript中如何通过栈来管理多个执行上下文。
13
+
14
+ 程序执行进入一个执行环境时,它的执行上下文就会被创建,并被推入执行栈中(入栈)。
15
+ 程序执行完成时,它的执行上下文就会被销毁,并从栈顶被推出(出栈),控制权交由下一个执行上下文。
16
+
17
+ JavaScript中每一个可执行代码,在解释执行前,都会创建一个可执行上下文。按照可执行代码块可分为三种可执行上下文。
18
+
19
+ 全局可执行上下文:每一个程序都有一个全局可执行代码,并且只有一个。任何不在函数内部的代码都在全局执行上下文。
20
+ 函数可执行上下文:每当一个函数被调用时, 都会为该函数创建一个新的上下文。每个函数都被调用时都会创建它自己的执行上下文。
21
+ Eval可执行上下文:Eval也有自己执行上下文。
22
+
23
+ 因为JS执行中最先进入全局环境,所以处于"栈底的永远是全局环境的执行上下文"。而处于"栈顶的是当前正在执行函数的执行上下文",当函数调用完成后,它就会从栈顶被推出(理想的情况下,闭包会阻止该操作,闭包后续文章深入详解)。
24
+ "全局环境只有一个,对应的全局执行上下文也只有一个,只有当页面被关闭之后它才会从执行栈中被推出,否则一直存在于栈底"
25
+ 看个例子:
26
+ let name = '蜗牛';
27
+
28
+ function sayName(name) {
29
+ sayNameStart(name);
30
+ }
31
+ function sayNameStart(name) {
32
+ sayNameEnd(name);
33
+ }
34
+ function sayNameEnd(name) {
35
+ console.log(name);
36
+ }
37
+ 复制代码当代码进行时声明:
38
+
39
+ 执行sayName函数时,会把直接函数压如执行栈,并且会创建执行上下文,执行完毕编译器会自动释放:
40
+
41
+ ## 存储栈的应用
42
+
43
+ ### LRU
44
+ LRU
45
+ 在操作系统中, LRU 是一种常用的页面置换算法。其目的在于在发生缺页中断时,将最长时间未使用的页面给置换出去。
46
+ 要能知道使用最少的键值对 !!!
47
+ 1.使用秘钥取数据时,就把当前的秘钥移动到数组的最后一项
48
+ 2.数组的第一项就是使用长时间未使用的缓存数据
49
+
50
+ ### 有效的括号
Original file line number Diff line number Diff line change
1
+ // 给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
2
+
3
+ // 有效字符串需满足:
4
+
5
+ // 左括号必须用相同类型的右括号闭合。
6
+ // 左括号必须以正确的顺序闭合。
7
+
8
+ var isValid = function ( s ) {
9
+ const n = s . length ;
10
+ if ( n % 2 === 1 ) {
11
+ return false ;
12
+ }
13
+ const map = {
14
+ "}" : "{" ,
15
+ ")" : "(" ,
16
+ "]" : "[" ,
17
+ }
18
+ const tisk = [ ] ;
19
+ for ( let i = 0 ; i < n ; i ++ ) {
20
+ const key = s . charAt ( i ) ;
21
+ if ( key == '}' || key == ')' || key == ']' ) {
22
+ if ( ! tisk . length || tisk [ tisk . length - 1 ] !== map [ key ] ) {
23
+ return false
24
+ } else {
25
+ tisk . pop ( )
26
+ }
27
+ } else {
28
+ tisk . push ( key )
29
+ }
30
+ }
31
+ return ! tisk . length
32
+ } ;
You can’t perform that action at this time.
0 commit comments