1、基础数据结构
1.1数据结构种类
数组
栈
队列和双端队列
链表
集合
字典和散列表
递归
树
二叉堆和堆排序
在写每个知识点的时候 我自己总结的方式是按照定义>javascript实现方式>对应的方法>算法实现的结构去写的 后面有想法在继续补充
1.2 数组
1.2.1 数组定义
js数组其实就是API的调用 是一种最简单的内存数据结构 数组存储一系列同一种数据类型的值
注:javascript中数组可以保存不同类型的值 但是一般不推荐哈
1.2.2 数组创建
在javascript中有两种创建数组的方式
1.使用Array构造函数
let shuzu=new Array();
注意:括号里面参数可以有参数,若为一个数字,表示该数组的长度,如果为多个数字或者一个(多个)非数字表示的是传递数组中应该包含的值。
2.使用数组字面量
let shuzu=[];
1.2.3 数组方法
添加元素 (首尾)
删除元素(首尾)
1、在数组末尾添加元素
使用push方法
numbers.push(11);
原生的方法:
numbers[numbers.length] = 10;
在Javascript中,数组是可以修改的对象,如果要添加元素,会动态生长,所以直接赋值给数组最后一个空位即可
2、在数组开头插入元素
使用unshift方法
numbers.unshift(10);
3从数组末尾删除元素
使用pop方法;
numbers.pop();
4、数组开头删除元素
使用shif方法
number.shif();
5、任意位置添加或者删除元素
使用splice方法:
splice接受多个参数
number.splice(4.,0,6,4)
第一个参数标识要删除或者插入的元素索引值
第二个参数是删除元素的个数,这个例子我们要添加元素所以第二个删除元素的个数为0.
第三个参数往后,就是我们 要添加到数组里面的值
1.2.4 数组的扩展
二维数组本质上是以数组作为数组元素的数组,即“数组的数组”,
类型说明符 数组名[常量表达式][常量表达式]。二维数组又称为矩阵,
行列数相等的矩阵称为方阵。对称矩阵a[i][j] = a[j][i],
对角矩阵:n阶方阵主对角线外都是零元素
var arr = [[1,2],[‘a’,‘b’]];
console.log(arr[1][0]); //a 第2列第1行所在的元素
1.2.5 javascript常用的数组方法
1、concat(),连接两个或者更多的数组,并返回一个新的数组**
2、ES6:copyWithin(),从数组的指定位置复制元素到数组的指定位置。语法:array.copyWithin(target, start, end)
3、ES6:entries(),返回数组的迭代对象
4、every(),检测数组所有元素是否都符合指定条件,接收一个函数作为参数,用于检测数组中的元素
5、ES6:fill(),将一个固定的值替换数组里面的元素。语法:array.fill(value, start, end)
6、filter(),返回一个数组,里面包含符合条件的元素
7、find(),返回数组中符合条件的第一个元素
8、findIndex(),返回数组中符合条件的第一个元素的所在位置
9、forEach(),数组每个元素都执行一次回调函数
10、ES6:from(),将伪数组转换为真正的数组
11、ES6:includes(),判断数组中是否函数指定的值,如有返回true,否则返回false
12、indexOf(),返回数组中指定元素的位置,如果数组中没有指定的元素则返回-1
13、isArray(),判断一个对象是否为数组,是 返回true,不是 返回false
15、ES6:keys(),从数组创建一个包含数组键的可迭代对象
16、lastIndexOf(),返回指定的元素在数组中最后出现的位置,在数组的后面开始搜索
17、map(),返回一个新数组,数组中的元素是原始数组的元素调用函数之后处理的值
18、pop(),删除数组的最后一个元素,并返回删除的元素
19、push(),在数组后面添加新元素,并返回数组新的长度
20、reduce(),将元素的值计算为一个值,从左到右
21、reduceRight(),将元素的值计算为一个值,从右到左
22、reverse(),反转数组元素的排列顺序
23、shift(),删除并返回数组第一个元素
24、unshift(),向数组的最前面添加新元素,并返回新的数组长度
25、slice(),返回指定的数组元素,第一个参数是开始的位置,第二个是结束位置(不包含结束位置的元素)
26、splice(),添加和删除数组中的元素,第一个参数是要删除的元素的开始位置,第二个参数是要删除的元素的个数。第三个以及以后的参数都是添加到数组中的新元素
27、some(),检测数组中是否含有指定的元素,有的话就返回true,没有就返回false
28、sort(),对数组进行排序,可以接收一个比较函数
29、toString(),将数组转为字符串,并返回结果
30、valueOf(),返回数组对象的原始值
常用的我已经加粗了!!!
1.2.6 类型数组
由于javascript与c和Java等语言不同,javascript数组不是强类型。可以存储任意类型数据
那么如何让javascript的数组也存储单一的数据类型呢?
这个就用到类型数组。
具体语法:
let myArray = new TypedArray(length)
//在实际使用中 把TypedArray换成下面列表中需要的类型

1.2.7TypeScript中的数组
Typescript中最简单的方法是使用「类型 + 方括号」来表示数组
let fibonacci: number[] = [1, 1, 2, 3, 5];
数组的项中不允许出现其他的类型:
在使用数组方法时,对应增删改查的元素类型必须一致,否则会报错。
详解文章:
TypeScript 数组Array操作
1.3 栈
1.3.1 概述
栈是一种遵从先进后出(LIFO)原则的有序集合。
新添加或待删除的元素都保存在栈的末尾,称作栈顶,另一端就叫栈底。
在栈里,新元素都靠近栈顶,旧元素都接近栈底
用日常生活中的例子:
栈就像我们的衣服口袋,先放进去的东西后取出来,后放进去的东西能先取出来
栈被用在编程语言的编译器和内存中用于保存变量,方法调用等等,也被用于浏览器历史记录(浏览器的返回按钮)
1.3.2 基于javascript数组创建栈
在javascript中用数组创建一个栈一共7个步骤:
1、先声明一个stack类,用于存放栈
2、向栈中使用push添加元素(只能从栈顶添加)
3、从栈中使用pop方法移除元素(从栈顶移除)
4.查看栈顶元素(peek方法)
5.检查栈是否为空 方法为isEmpty 如果栈为空返回true 否则返回false
6.使用clear方法清空栈元素
7.可以开始使用stack类
经过上面的六步,stack已近具有了栈的特点。
代码实现:
1.3.3 基于javascript对象创建栈
前面我们已经学会使用数组来创建栈了,但在实际的应用中,处理大量数据的时候,需要评估如何使用数据是最高效的,使用数组的时间复杂度为0(n),n代表数组的长度,因为数组是一个有序集合,为了保证元素排序,会占用更多的内存我们需要迭代整个数组直到寻找到目标元素。
由此引出了对象创建栈
对象能直接获取元素,占用较少的内存空间,而且能够按照我们的要求排列数据。
操作步骤一共六步:
1、声明一个stack类
2、向栈中插入元素
3、验证栈是否为空和它的大小
4、从栈中弹出元素
5、查看栈值并将栈清空
6、创建tostring方法
代码实现:
//首先声明一个stack类
class stack {
constructor () {
this.count = 0 ; //使用count来记录栈的大小,也能帮助我们删除和添加元素
this.items = {};
}
}
//向栈中加入元素
push(element) {
this.items[this.count ] = element;
this.count ++ ;
}
//在js中,对象是键值对的形式表现出来,我们使用count作为items对象的键名,插入的元素则是它的值,插入元素后,我们把count++,以便于下一个变量值插入
//count属性也表示栈的大小,我们可以返回count的size来计算栈的大小
size(){
return this.count;
}
//验证栈是否为空
isEmpty(){
return this.count === 0;
}
//查看栈顶的值并将栈清空
peek{
if (this.isEmpty()){
return unerfined;
}
return this.items{this.items.length - 1};
}
//清空栈把值变为构造函数的初始值就ok
clear (){
this.items = {};
this.count = 0;
}
//也可以使用另外一种方法:
while (!this.isEmpty()){
this.pop();
}
//创建tostring方法
在前面的数组中没有提string方法,是因为数组内置就有tostring属性,使用对象的时候,就需要我们手动去穿件了
toString () {
if (this.isEmpty()){
return '';
}
let objStru=ing = '${this.items[0]}';
for (let i = 1 ; i < this.count; i++ ){
objString = '${objstring},${this.items[i]}';
}
return objstring ;
}
//如果栈是空的,返回空值就ok了
//如果不是空的。底部第一个元素作为字符串的初始值,然后迭代整个栈
至此,一个基于对象创建的栈就完成了
1.3.4 保护数据结构内部元素
在我们创建一个栈后,别的同事也可能要使用,我们想保护内部的元素,只允许改变我们暴露的元素,这个时候就提及到了保护数据结构内部元素:
主要有三种方法:
下划线命名定义
一部分开发者喜欢在javascript中使用下划线命名约定来标记一个属性为私有属性
下划线命名约定实在属性名称之间加一个下划线-,不过这种方法只是一种约定,不能保护数据,看不懂的程序员就gg了
代码实现:
class stack {
constructor () {
this._count = 0;
this._items = {};
}
}
使用symbol实现类
在es6中规定,symbol是不可变的,可以用作对象的属性
代码实现:
cosnt_items = symbol('stacItems');
class stack {
constoructor () {
this[_items] = [];
}
//栈的方法
}
使用weakMap实现类
weakMap就能确保属性私有,weakMap是键值对的存在,键是对象,值是属性。
1.3.5 javascript中用栈解决实际问题
使用栈实现阶乘的递归
使用栈来模拟5!的过程,首先将数字5到1压入栈,然后使用一个循环将数字挨个弹出并连乘
代码实现:
1 function fact(num) {
2 var stack=new Stack;
3 while(num>0){
4 stack.push(num--);
5 }
6 var sum=1;
7 while(stack.length>0){
8 sum*=stack.pop;
9 }
10 return sum;
11 }
12
13 console.log(fact(5)) //120
1.3.6 合法括号
下面的字符串中包含小括号,请编写一个函数判断字符串中的括号是否合法,所谓合法,就是括号成对出现
sdf(ds(ew(we)re)rwqw)qwrwq 合法
(sd(qwqe)sd(sd)) 合法
()()sd()(sd()dw))( 不合法
思路分析
括号存在嵌套关系,也存在并列关系,如果使用数组来存储这些括号,然后再想办法一对一的抵消掉,似乎可行。但是我们无法判断一个左括号对应的是哪一个右括号。在数组的角度思考这个问题,就有些困难。
现在,我们使用栈来解决这个问题
遇到左括号,就把做括号压入栈中
遇到右括号,判断栈是否为空,如果为空则说明没有左括号与之相对应,字符串括号不合法。如果栈不为空,则把栈顶元素移除,这对括号就抵消了。
当for循环结束,如果栈是空的,说明所有的左右括号都抵消了,如果栈力还有元素,则说明缺少右括号,字符串括号不合法。
代码实现:
function is_leagl_brackets(string){
var stack = new Stack();
for (var i = 0;i<string.length;i++) {
var item = string[i];
// 遇到做括号入栈
if(item == '('){
stack.push(item)
}else if (item == ')'){
// 遇到右括号,判断栈是否为空
if(stack.isEmpty()){
return false
}else {
stack.pop() // 弹出左括号
}
}
}
// 如果栈为空,说明字符串括号合法
return stack.isEmpty()
}
console.log(is_leagl_brackets('sdf(ds(ew(we)re)rwqw)qwrwq')) // true
console.log(is_leagl_brackets('(sd(qwqe)sd(sd))')) // true
console.log(is_leagl_brackets('()()sd()(sd()dw))(')) // false
供一个min方法,返回栈里的最小的元素,且时间复杂度为O(1)
function MinStack() {
var data_stack = new Stack();
var min_stack = new Stack();
// 用min_stack 记录每次 push 进来的元素之后,栈中的最小值
this.push = function (item) {
data_stack.push(item);
if(min_stack.isEmpty() || item < min_stack.top()){
min_stack.push(item)
}else {
min_stack.push(min_stack.top())
}
};
// 这样,每次pop之后,min_stack 也会将上次栈中的最小值弹出
this.pop() = function () {
data_stack.pop()
min_stack.pop()
}
this.min = function () {
return min_stack.top()
}
}
实际应用中还有许多,这里我就不挨个列举 了。
本文深入探讨JavaScript中的基础数据结构,重点讲解数组和栈。详细介绍了数组的定义、创建、方法及其扩展,包括二维数组和类型数组的概念。接着讨论栈的原理,通过JavaScript数组实现栈,并展示了如何保护数据结构内部元素。文章还给出了使用栈解决实际问题,如阶乘计算和合法括号判断的示例代码。
7049

被折叠的 条评论
为什么被折叠?



