数据结构复习(更新中)

栈结构

我们可以把栈想象成一个竖着的量筒,最先放进去的东西,在最下面。(栈结构其实就是一个受限的线性结构)
所以栈的特点是:先入后出(在一头添加或者删除)。在生活中,还是比较常见的,比如我们去吃自助餐拿的那个餐盘,我们取到的餐盘是最后放上去的,而最先放的餐盘在最下面。
在程序中,栈是怎么应用的呢?比如函数调用函数
A调用B,B中调用C,C中调用D
此时,可以看作A在栈底,然后是B、C、D
D结束,C才会结束,B才会结束,A才会结束。

栈结构的小测试

有六个元素,6,5,4,3,2,1的顺序进栈,下列哪一个不合法序列
A:5,4,3,6,1,2
B:4,5,3,2,1,6
C:3,4,6,5,2,1
D:2,3,4,1,5,6
答案:C
(走一下就知道了)

使用数组实现栈

// 方法和某一个对象的实例有联系,把函数称为方法,正常就是函数
        // 栈的封装
        function Stack() {
            this.items = [];
            // 1.将元素加入到栈
            Stack.prototype.push = function (element) {
                this.items.push(element)
            }
            // 2.从栈中取出元素
            Stack.prototype.pop = function () {
                return this.items.pop()
            }
            // 3.查看栈顶元素
            Stack.prototype.peek = function () {
                return this.items[this.items.length - 1]
            }
            // 4.判断栈是否为空
            Stack.prototype.isEmpty = function () {
                return this.items.length == 0
            }
            // 5.获取栈中元素的个数
            Stack.prototype.size = function () {
                return this.items.length;
            }
            // 6.内容以字符串返回
            Stack.prototype.toString = function () {
                let resultString = ''
                for (let i = 0; i < this.items.length; i++) {
                    resultString += this.items[i] + ''
                }
                return resultString;
            }
        }
// 栈的使用
        let stack1 = new Stack();
        stack1.push(20)
        stack1.push(10)
        stack1.push(10)
        stack1.push(7)
        console.log(stack1)
        console.log(stack1.pop())
        console.log(stack1.peek())
        console.log(stack1.size())
        console.log(stack1.isEmpty())
        console.log(stack1.toString())

在这里插入图片描述

封装十转化二函数

我们知道十进制转化二进制,就是和2整除,直到结果为0为之。(二进制是满2进1)比如100转化二进制过程如下:
在这里插入图片描述

// 函数:十进制转换二进制
        function toBin(decNumber) {
            // 1.定义一个栈对象
            let stack = new Stack();
            // 2.循环操作
            while (decNumber > 0) {
                //获取余数,放到栈
                stack.push(decNumber % 2)
                // 获取整除结果
                decNumber = Math.floor(decNumber / 2)

            }
            //3.从栈中取出01
            let binString = ''
            while (!stack.isEmpty()) {
                binString += stack.pop()
            }
            return binString
        }
        // 测试
        console.log(toBin(100))

在这里插入图片描述
下面,我们用计算器检验一下结果是否正确
在这里插入图片描述

队列结构

我们可以把栈想象成一个横着的管道,最先放进去的东西,在管道的最头。(队列结构也是一个受限的线性结构)
所以队列的特点是:先入先出(在队列尾部添加,在队列顶部删除)。在生活中,还是比较常见的,比如我们去吃排队在电影院买票,我们先排队的永远是先被处理买票的。
在程序中,队列是怎么应用的呢?比如线程
有很多个线程,会依照次序来启动线程进行处理对应的任务。

使用数组实现队列

其实是不建议这种的,因为数组实现队列,性能没有链表实现队列要好,数组在头删除一个元素,后面的元素都要依次往前进,所以性能有点不好。

// 封装队列
        function Queue() {
            // 属性
            this.items = [];
            // 方法
            // 1.加入元素
            Queue.prototype.enqueue = function (element) {
                this.items.push(element);
            }
            // 2.删除(数组从头删除,性能不高,因为删除一个,后面都会移动,链表性能会更高)
            Queue.prototype.dequeue = function () {
                return this.items.shift();
            }
            // 3.查看
            Queue.prototype.front = function () {
                return this.items[0]
            }
            // 4.查看是否为空
            Queue.prototype.isEmpty = function () {
                return this.items.length === 0
            }
            // 5.队列元素个数
            Queue.prototype.size = function () {
                return this.items.length
            }
            // 6.tostring
            Queue.prototype.toString = function () {
                let reselutString = '';
                for (let i = 0; i < this.items.length; i++) {
                    reselutString += this.items[i] + ''
                }
                return reselutString;
            }
        }
// 队列的使用
        let q = new Queue();
        q.enqueue(300)
        q.enqueue(200)
        q.enqueue(400)
        q.enqueue(33)
        console.log(q)
        console.log(q.dequeue())
        console.log(q.front())
        console.log(q.isEmpty())
        console.log(q.size())
        console.log(q.toString())

在这里插入图片描述

链表

跟数组类似,如果对于删除头的这种操作,链表的性能要高于数组,如果对于删除某个位置的元素,链表只能从头开始访问,无法通过下标直接访问,需要一个个去访问,这时候数组的性能要高于链表。
链表:每个元素由一个存储本身元素的节点和一个指向下一个元素的引用(指针)所组成。
链表在插入和删除时,它的时间复杂度为O(1),相对数组效率高很多。
比如一个火车,他由一个火车头和很多个车厢组成。这就很像链表。
在这里插入图片描述

封装链表

单向链表

 //封装类
        function linkList() {
            //内部类
            function Node(data, next) {
                this.data = data;
                this.next = null;
            }
            // 属性
            this.head = null;
            this.length = 0;
            // 1.追加方法
            linkList.prototype.append = function (data) {
                // 创建新节点
                let newNode = new Node(data);
                // 判断是否添加的是第一个节点
                if (this.length === 0) {
                    this.head = newNode;
                } else { //不是第一个节点
                    // 找到最后一个节点
                    let current = this.head;
                    while (current.next) {
                        current = current.next;
                    }
                    // 让最后节点的next指向新的节点
                    current.next = newNode;
                }
                this.length += 1;
            }
            // 2.tostring方法
            linkList.prototype.toString = function () {
                let current = this.head;
                let listString = '';
                // 循环获取一个个的节点
                while (current) {
                    listString += current.data + ' ';
                    current = current.next;
                }
                return listString;
            }
            // 3.insert方法
            linkList.prototype.insert = function (position, data) {
                // 对position进行越界判断,不能负数
                // 长度判断,不能超过链表本身的长度
                if (position < 0 || position > this.length) return false;
                // 先创建节点
                let newNode = new Node(data);
                if (position === 0) {
                    newNode.next = this.head;
                    this.head = newNode;
                } else {
                    let index = 0;
                    let current = this.head;
                    let previous = null;
                    // index++ 先判断,在++
                    while (index++ < position) {
                        previous = current;
                        current = current.next;
                    }
                    newNode.next = current;
                    previous.next = newNode;
                }
                this.length += 1;
                return true;
            }
            //4.get方法
            linkList.prototype.get = function (position) {
                if (position < 0 || position >= this.length) return null;
                // 2.获取对应的数据
                let current = this.head
                let index = 0;
                while (index++ < position) {
                    current = current.next;
                    // index++;
                }
                return current.data
            }
            // 5.indexOf
            linkList.prototype.indexOf = function (data) {
                let current = this.head;
                let index = 0;
                // 开始查找
                while (current) {
                    if (current.data == data) {
                        return index;
                    }
                    current = current.next;
                    index += 1;
                }
                // 找到最后没有找到
                return -1;
            }
            // 6.updata
            linkList.prototype.update = function (position, data) {
                if (position < 0 || position >= this.length) return false;
                // 查找正确的节点
                let current = this.head;
                let index = 0;
                while (index++ < position) {
                    current = current.next
                }
                // 将data修改
                current.data = data;

                return true;
            }
            // 7.remove(data)
            linkList.prototype.remove = function (data) {
                // 1.根据data获取data的位置
                let position = this.indexOf(data)
                // 2.根据位置信息删除节点
                return this.removeAt(position);
            }
            // 8.removeAt(position)
            linkList.prototype.removeAt = function (position) {
                if (position < 0 || position >= this.length) return false;
                let current = this.head;
                if (position === 0) {
                    this.head = this.head.next;
                } else {
                    let index = 0;

                    let previous = null;
                    while (index++ < position) {
                        previous = current;
                        current = current.next;
                    }
                    previous.next = current.next;
                }
                this.length -= 1;
                return true;
            }
        }
        let l = new linkList();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值