学习JavaScript数据结构与算法(一)

175 阅读4分钟

前言

由于自己数据结构和算法能力实在太差,所以开始记录看《学习JavaScript数据结构与算法(第三版)》的笔记,会记录一些自己不太熟悉或者有意思的东西,自己熟悉的东西就不往上写了,加油吧!

数组和栈

数组

1. 求斐波那契数列的前20个数

已知斐波那契数列中的前两项是1,从第三项开始,每一项都等于前两项之和,从第三项开始,每一项都等一前两项之和。

const fibonacci = [];
//初始定义前两个斐波那契数列为1
fibonacci[1] = 1;
fibonacci[2] = 1;
//获取从3-20的数字
for(let i=0 ; i<20 ; i++){
    fibonacci[i] = fibonacci[i-1] + fibonacci[i-2];
}
//打印斐波那契数列
for(let i=0 ; i<fibonacci.length ; i++){
    console.log(fibonacci[i])
}

如果想知道更多的斐波那契数列的数,在第一个for循环中改变第二个判断值

2.数组的一些方法

push方法:把元素添加到数组的末尾

pop方法:删除数组最靠后的元素

push和pop方法可以用数组模拟栈

unshift方法:把元素添加到数组的开头,将所有元素索引后移一位,然后添加进

shift方法:删除第一个元素

通过shift和unshift方法可以模拟基本的队列数据结构

splice方法: splice接受的第一个参数,表示要删除或插入的元素的索引值,

​ 第二个参数是删除元素的个数(可以为0,不删除元素)

​ 第三个参数往后,就是添加到数组里的值

concat方法:合并数组

迭代方法
1. for循环
2. every方法

会迭代数组中每个元素,直到返回false

3. some方法

对迭代数组中每个元素,直到返回true

4. forEach方法,

迭代整个数组

5. map方法

返回一个新的数组,由函数返回的true或者falsse

6. filter方法

返回的新的数组由函数返回true的元素组成

ES6新增数组方法

for...of循环

for (const n of numbers){ }

3.二维数组

myMatrix[i][j]可以通过这样的方式实现一个矩阵

如果想看这个矩阵的输出:i为行,j为列

function printMatrix(myMatrix){
    for(let i=0 ; i<myMatrix.length ; i++){
        for(let j=0 ; j<myMatrix[i].length ; j++){
            console.log(myMatrix[i][j]);
    }
}

4.排序

reserve方法:

反序数组内元素

sort方法:

排序默认字符串,如果排序数字从小到大:numbers.sort((a,b) => a-b)

5.搜索

find方法和findIndex方法

find和findIndex的不同之处在于,find方法返回第一个满足条件的值,findIndex方法则返回这个值在数组里的索引。

如果没有满足条件的值,find会返回undefined,而findIndex返回-1。

includes方法

如果数组里存在某个元素,includes方法会返回true,否则返回false。

6.输出数组为字符串

toString

把数组所有元素输出为一个字符串

join方法

用不同的分隔符把元素隔开

Array.join('-')用 ’-‘ 将元素隔开

栈是一种遵从后进先出(LIFO)原则的有序集合。新添加或待删除的元素都保存在栈的同一端,称作栈顶,另一端就叫栈底。在栈里,新元素都靠近栈顶,旧元素都接近栈底。

栈也被用在编程语言的编译器和内存中保存变量、方法调用等,也被用于浏览器历史记录(浏览器的返回按钮)。

1. 栈的方法

1. push(element(s))

添加一个(或几个)新元素到栈顶

2. pop()

移除栈顶的元素,同时返回被移除的元素

3. peek()

仅仅返回栈顶的元素,不对栈做任何修改

4. isEmpty ()

如果栈内没有任何元素,返回true,否则返回false

5. clear()

移除栈里的所有元素

6. size()

返回栈里的元素个数,和length类似

2.创建栈

1. 使用ES2015(ES6)语法创建了Stack类。

ES2015类是基于原型的。尽管基于原型的类能节省内存空间并在扩展方面优于基于函数的类,但这种方式不能声明私有属性(变量)或方法。

const stack = new Stack();
console.log(Object.getOwnPropertyNames(stack))   //{1}
console.log(Object.keys(stack))                  //{2}
console.log(stack.items)                         //{3}

行{1}和行{2}的输出结果是["count", "items"]。这表示count和items属性是公开的,我们可以像行{3}那样直接访问它们。根据这种行为,我们可以对这两个属性赋新的值。

2. ES6 中Symbol

ES2015新增了一种叫作Symbol的基本类型,它是不可变的,可以用作对象的属性。看看怎么用它在Stack类中声明items属性(我们将使用数组来存储元素以简化代码)。

3.栈的应用
十进制转换二进制
function decimalToBinary(decNumber){
    const remStack = new Stack();
    let number = decNumber;
    let rem;
    let binaryString = '';
    
    while(number > 0){                     // 当除法结果不为0时
        rem = Math.floor(number % 2);      // 获取余数并向下取整,丢弃小数部分
        remStack.push( rem );              // 存入栈中
        remStack = Math.floor(number / 2)  // 结果继续除以2
    }
    while(!remStack.isEmpty()){
        binaryString += remStack.pop.toString();  //用pop方法把栈中的元素移除后连接成字符串
    }
    return binaryString;
}
十进制转换任意进制数
function baseConverter(decNumber,base){
    const remStack = new Stack();
    const digits = '0123456789ABCDEFGHJKLMNOPQRSTUVWXYZ';  //转化一些字母
    let number = decNumber;
    let rem;
    let baseString = '';
    
    if(!(base >= 2 && base<=36)){
        return '';
    }
    
    while(number > 0){
        rem = Math.floor(number % base);      
        remStack.push( rem );             
        remStack = Math.floor(number / base)
    }
    while(!remStack.isEmpty()){
        baseString += digits[remStack.pop()];
    }
    return baseString;
}

base是转换为几进制数

将十进制转成十六进制时,余数是0~9加上A、B、C、D、E和F(对应10、11、12、13、14和15)。因此,我们需要对栈中的数字做个转化才可以(行{6}和行{7})。因此,从十一进制开始,字母表中的每个字母将表示相应的基数。字母A代表基数11, B代表基数12