JavaScript常用的数据结构和算法 ——封装栈类

简单说说

最近这几天学习到了平台期了,就是一直处于一个相同的学习水平,怎么也进步不了。之前看jQuery学习了一些常用的方法,操作dom元素、事件、动画效果、ajax等,总感觉自己只是了解了表面,想深入呢,也不知道怎么去深入。哎,又有点小无措的感觉了。
然后呢,七月过去了一半,es678也过了一遍,了解了js新增的语法以及异步编程。对于异步编程现在掌握不好,因为真的真的真的不会后端,什么抓取数据、异步交互都不知道怎么操作的。仔细想了想,剩下的半个月俩星期,我要把HTML5深入一下,其中穿插着复习css重难点、js核心内容。一直学习js会有点枯燥的感觉,所以又增加了数据结构与算法的学习,3-4天学习一个呗。反正以后都会用到的,权当放松了。哈哈哈哈哈哈。

数组

数组也是数据结构的一类,js中的数组封装是相当完整的了,好好学习使用就好了。
这里总结一下数组的优缺点。

优点

  • 效率高。通过下标索引的对元素进行高效的操作
  • 灵活度高。可以在数组任意位置删除、插入元素

缺点

  • 性能低。在数组末尾插入和删除元素时,还体现不出来。但是当对数组的第一个元素插入或删除时,这时候就体现了性能低。在插入时,需要把后面的元素一一的向后移动;在删除时,需要把后面的元素一一向前移动一个位置。数组中的元素需要不断的移动,体现性能低。
  • 耗时。耗费时间多

这里补充一点其他语言中的数组,与js中的数组还有一点差别。
比如Java中的ArrayList。
ArrayList扩容机制
举个例子,第一次申请一个空间,这个空间最多能放5个元素,当我们需要放第6个元素时,因为第一次申请的空间不够,所以扩容一倍。

  1. 首先申请一个新的能放10个元素的空间
  2. 再把原来的数据复制到这个新空间
  3. 然后再新空间中追加数据
  4. 当空间再次用完之后,循环第一步操作,申请20个元素的空间。依次类推,每次扩容上一次空间的一倍。

扩容机制这一点体现了数组这种数据结构的耗时。
这些只是我所了解的一些知识,没有深入。

栈的特点:后进先出(LIFO)。
换句话说就是先进去,后出来。栈的过程就是压栈弹栈的过程,相对来说比较简单。

通过在函数调用时会遇到,比如说执行A函数,A压栈;A函数调用B函数,B压栈;B函数内部又调用了C函数,C压栈。这样,C函数先执行完毕返回值,弹出C;接着回到B函数执行,B函数执行完毕返回后,弹出B;到A函数,A函数执行完弹出A。整个过程结束。
上面的过程我们叫做函数调用栈。在js中是非常常见并且常用的。

基于数组封装栈

这里的封装,主要实现了常用的几个方法,进栈、弹栈、查看元素、判断栈是否为空、查看元素个数
方式一:

        function Stack() {
            // 1.栈中的元素
            this.item = [];
            // 2.栈的常用操作
            // 在原型上编程 共享的方法
            // 2.1 进栈
            Stack.prototype.push = function (element) {
                return this.item.push(element);
            }
            // 2.2 出栈
            Stack.prototype.pop = function () {
                // 返回出栈元素
                return this.item.pop();
            }
            // 2.3 查看栈顶元素  -- 数组中的最后一个元素
            Stack.prototype.top = function () {
                return this.item[this.item.length - 1];
            }
            // 2.4 判断栈是否为空
            Stack.prototype.isEmpty = function () {
                return this.item.length == 0;
            }
            // 2.5 查看栈中的元素
            Stack.prototype.showAll = function () {
                return this.item.join(" ");
            }
            // 2.6 查看栈中的元素个数
            Stack.prototype.size = function () {
                return this.item.length;
            }
        }

方式二:

        class Stack {
            static item = [];
            // constructor() {
            //     this.item = [];
            // }
            push(element) {
                return Stack.item.push(element);
            }
            pop() {
                return Stack.item.pop();
            }
            top() {
                return Stack.item[Stack.item.length - 1];
            }
            isEmpty() {
                return Stack.item.length == 0;
            }
            showAll() {
                return Stack.item.join(" ");
            }
            size() {
                return Stack.item.length;
            }
        }

测试:

        let stack = new Stack();
        stack.push(6);
        stack.push(5);
        stack.push(4);
        stack.push(3);
        console.log(stack.showAll()); // 6 5 4 3
        console.log(stack.top()); // 3


        stack.pop(); // 3
        stack.pop(); // 4
        console.log(stack.showAll()); // 6 5
        console.log(stack.top()); // 5
        console.log(stack.isEmpty()); // false 不空
        console.log(stack.size()); // 2

JavaScript常用的数据结构和算法 ——封装栈类_第1张图片

栈类应用 十进制转换二进制

十进制转换二进制数的原理是:倒取余数法。
这里的倒取,我们可以看作是压栈的过程,最后通过弹栈来获取。

例子:

        计算 10
        10/2  余数:0
        5/2   余数:1
        4/2   余数:0
        2/2   余数:1
        0/2   循环结束

每次使用上一次的商继续计算。这个功能,封装一个方法。

        // 使用栈实现十进制转换二进制
        // 倒取余数法 —— 余数压栈的操作
        function decToBin(decNumber) {
            // 1. 需要一个栈容器放余数
            let stack = new Stack();
            // 循环取余数  直到商为0 跳出循环
            // 2. 商小于等于0  不能再进行运算
            while (decNumber > 0) {
                // 2.1 余数压栈
                stack.push(decNumber % 2);
                // 2.2 使用上一次的商再次取余数 更新参数为上一次数/2的商 向下取整
                decNumber = Math.floor(decNumber / 2);
            }
            // 3. 出栈 只要栈不空就一直弹栈
            let binaryString = [];
            while (!stack.isEmpty()) {
                binaryString.push(stack.pop());
            }
            return binaryString.join("");
        }
        console.log(decToBin(10)); // 1010

ok,今天新增额外学习任务完成!
加油加油!!!!

你可能感兴趣的:(算法)