File tree Expand file tree Collapse file tree 7 files changed +173
-35
lines changed Expand file tree Collapse file tree 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- }
51
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