• 前端编程应该了解的数据结构——栈、队列


    数据结构

    数据结构并没有官方的定义,在民间有各种定义;

    1、数据结构是数据对象,以及存在于该对象的实例和组成实例的数据元素之间的各种联系;

    2、数据结构是计算机中存储、组织数据的方式,通常情况下,精心选择的数据结构可以带来最有效的算法;

    3、数据结构是抽象数据类型的物理实现

    数据结构的实现离不开算法,算法Algorithm,单词意思为解决问题的方法和步骤

    算法的定义:

    1、一个有限指令集,每条指令的描述不依赖于语言

    2、接受一些输入(有时不需要输入)

    3、产生输出

    4、一定有限步骤后终止

    常用的数据结构

    八种:栈、队列、链表、集合、字典、树、图、哈希表

    每一种都有其对应的应用场景, 不同的数据结构的不同操作性能是不同的:

    • 有的查询性能很快,有的插入速度很快,有的是插入头和尾速度很快

    • 有的做范围查找很快,有的允许元素重复,有的不允许重复等等

    • 在开发中如何选择,要根据具体的需求来选

    在学习数据结构后,可根据业务需求选择响应的数据结构,数据结构是每一个程序员都应该学习的课程, 数据结构和语言无关, 基本常见的编程语言都有直接或者间接的使用上述常见的数据结构。

    今天讲解栈和队列

    栈的基本特性:

    1、与数组相似,但它是一种受限制的线性结构

    2、看作存取数据的一个容器,只能在容器的一端操作数据

    3、LIFO(last in first out ),表示先进后出,意思就是第一个进去的元素,只能在最后一个出来

    4、向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素

    5、从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

    简单画出简图:

     在前端中简单实现对栈的操作:

    用es6新增的class类封装栈的常用操作:

    push()向栈顶添加一个元素;

    pop()移除栈顶元素,并返回这个值;

    peek()返回栈顶元素;

    isEmpty()返回布尔值,栈内无任何元素返回true,否则返回false;

    clear()清除栈内的所有元素

    size()返回栈内元素的个数

    代码实例:

    1. class Stack{
    2. constructor(){
    3. this.item=[]
    4. }
    5. //入栈
    6. push(i){
    7. this.item.push(i)
    8. }
    9. //出栈 删除最后一个元素并返回
    10. pop(){
    11. return this.item.pop()
    12. }
    13. //peek 返回最后一个元素
    14. peek(){
    15. return this.item[this.item.length-1]
    16. }
    17. //isEmpty是否为空
    18. isEmpty(){
    19. return this.item.length==0
    20. }
    21. // clear清空栈
    22. clear(){
    23. this.item=[]
    24. }
    25. //栈内元素的个数
    26. size(){
    27. return this.item.length
    28. }
    29. }

    实际应用:利用栈实现十进制转换为二进制

    1. class Stack{
    2. constructor(){
    3. this.item=[]
    4. }
    5. //入栈
    6. push(i){
    7. this.item.push(i)
    8. }
    9. //出栈 删除最后一个元素并返回
    10. pop(){
    11. return this.item.pop()
    12. }
    13. //peek 返回最后一个元素
    14. peek(){
    15. return this.item[this.item.length-1]
    16. }
    17. //isEmpty是否为空
    18. isEmpty(){
    19. return this.item.length==0
    20. }
    21. // clear清空栈
    22. clear(){
    23. this.item=[]
    24. }
    25. //栈内元素的个数
    26. size(){
    27. return this.item.length
    28. }
    29. }
    30. function bin(el){
    31. var stack=new Stack()
    32. // console.log(stack);
    33. //余数
    34. while(el>0){
    35. let yushu=el%2
    36. stack.push(yushu)
    37. el=Math.floor(el/2)
    38. }
    39. console.log(stack.item.length);
    40. var str=""
    41. while(stack.isEmpty()==false){
    42. str=str+stack.item.pop()
    43. }
    44. return str
    45. }
    46. console.log(bin(8)); //打印结果1000

    队列

    队列也是受限制的线性表,它的基本特性:

    FIFO先进先出,意思就是先进入队列的元素先出去;

    在队列前端删除元素,在后端插入元素。

    画出简图:

    在生活中很多例子都像队列,例如食堂排队打饭,先来排队的人,优先打到饭离开。

    队列的常见操作:

    enqueue()向队列尾部添加一个新的元素;

    delqueue()移除队列中队首的那个元素;

    front()返回队列队首的那个元素;

    isEmpty()返回布尔值,如果队列不含任何元素返回true,反之false;

    size()返回队列包含元素的个数。

    代码实现:

    1. //封装一个队列
    2. class Queue{
    3. constructor(){
    4. this.item=[]
    5. }
    6. //入队
    7. enqueue(el){
    8. this.item.push(el)
    9. }
    10. //出队
    11. delqueue(){
    12. return this.item.shift()
    13. }
    14. // 返回首元素
    15. front(){
    16. return this.item[0]
    17. }
    18. //判空
    19. isEmpty(){
    20. return this.item.length==0
    21. }
    22. //元素个数
    23. size(){
    24. return this.item.length
    25. }
    26. }

    通过队列来实现一个击鼓传花的小游戏,每次数到3的人被淘汰,下一个人又从1开始数。

    1. function jigu(arr){
    2. //创建队列
    3. var queue= new Queue()
    4. //入队
    5. arr.forEach(el => {
    6. queue.enqueue(el)
    7. });
    8. //数数
    9. let count=1
    10. while(queue.size()>1){
    11. if(count<3){
    12. queue.enqueue(queue.delqueue)
    13. count++
    14. }else{
    15. //等于3时
    16. queue.delqueue()
    17. count=1
    18. }
    19. }
    20. return queue.front()
    21. }
    22. var arr=["鲨鱼辣椒","蜻蜓队长", "嶂螂恶霸", "金龟次郎", "蜗了莱莱","铁甲小宝"]
    23. console.log(jigu(arr)); //鲨鱼辣椒

    此外,我们还需要认识一种队列——优先级队列,普通的队列插入一个元素, 数据会被放在后端, 并且需要前面所有的元素都处理完成后才会处理前面的数据。在有些情况下,元素是要插队的,插入的元素与已存在队列的元素进行优先级比较,将元素插入到正确的位置。

    队列优先级的实现:

    实现思路:添加元素时,如果队列内无元素,则直接添加;如果有,将当前的优先级和队列中已经存在的元素优先级进行比较, 以获得自己正确的位置。

    1. class Node{
    2. constructor(el,priority){
    3. this.data=el,
    4. this.priority=priority
    5. }
    6. }
    7. class PriorityQueue{
    8. constructor(){
    9. this.item=[]
    10. }
    11. enqueue(el,priority){
    12. //创建新节点 或者直接赋值 let newnode={data:el,priority:priority}
    13. let newnode=new Node(el,priority)
    14. if(this.item.length==0){
    15. //空队列
    16. this.item.push(newnode)
    17. }else{
    18. let isAdd=false
    19. //非空队列
    20. for (let i = 0; i < this.item.length; i++) {
    21. if (newnode.priority<this.item[i].priority) {
    22. this.item.splice(i,0,newnode)
    23. isAdd=true
    24. break
    25. }
    26. }
    27. //如果遍历完都没有比它优先级大的,就加在最后
    28. if (!isAdd) {
    29. this.item.push(newnode)
    30. }
    31. }
    32. }
    33. }
    34. let pq=new PriorityQueue()
    35. pq.enqueue("qqq",10)
    36. pq.enqueue("qqq",100)
    37. pq.enqueue("qqq",101)
    38. console.log(pq.item);

  • 相关阅读:
    Redis的哨兵模式搭建
    Acwing 3302. 表达式求值
    Ts常见报错解决方案
    【pandas小技巧】--DataFrame的显示样式
    C++ 友元
    BuildApkPlugin 自动化编译打包
    Vue 3 打印解决方案:Vue-Plugin-HiPrint
    设计模式-责任链模式(Chain of Responsibility)
    GIT技巧
    1023 Have Fun with Numbers
  • 原文地址:https://blog.csdn.net/m0_59345890/article/details/126469276