[面试专题]数据结构和算法-JS之魂

news/2024/6/15 2:14:58 标签: 面试, 数据结构与算法, javascript

数据结构和算法-JS之魂

标签(空格分隔): 未分类


数据结构:

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

class Stack {
    constructor() {
        this.items = []
    }
    push(element) {
         this.items.push(element)
    }
    pop() {
        return this.items.pop()
    }
    clear() {
        this.items = []
    }
    print() {
        console.log(this.items.toString())
    }
    // 属性
    get peek() {
        return this.items[this.items.length - 1]
    }
    get size() {
        return this.items.length
    }
}
  • 队列:与上相反,一种遵循先进先出 (FIFO / First In First Out) 原则的一组有序的项;队列在尾部添加新元素,并从头部移除元素。最新添加的元素必须排在队列的末尾。

class Queue {
  constructor(items) {
    this.items = items || []
  }
  // 普通队列
  enqueue(element) {
    this.items.push(element)
  }
  // 优先队列的构造方法
  // enqueue(element, priority) {
  //   const queueElement = { element, priority }
  //   if (this.isEmpty) {
  //     this.items.push(queueElement)
  //   } else {
  //     const preIndex = this.items.findIndex((item) => queueElement.priority < item.priority)
  //     if (preIndex > -1) {
  //       this.items.splice(preIndex, 0, queueElement)
  //     } else {
  //       this.items.push(queueElement)
  //     }
  //   }
  // }
  dequeue() {
    return this.items.shift()
  }
  front() {
    return this.items[0]
  }
  clear() {
    this.items = []
  }
  print() {
    console.log(this.items.toString())
  }
  get size() {
    return this.items.length
  }
  get isEmpty() {
    return !this.items.length
  }
}
// 循环队列,要点在于index的计算
class LoopQueue extends Queue {
    constructor(items) {
        super(items)
    }
    getIndex(index) {
        const length = this.items.length
        return index > length ? (index % length) : index
    }
    find(index) {
        return !this.isEmpty ? this.items[this.getIndex(index)] : null
    }
}
  • 链表:存储有序的元素集合,但不同于数组,链表中的元素在内存中并不是连续放置的;每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(指针/链接)组成。

class linkNode {
  constructor(ele) {
    this.element = ele;
    this.next = null;
  }
}
class singLinkList {
  constructor() {
    this.item = [];
    this.head = null;
    this.length = 0;
  }
  append(ele) {
    const node = new linkNode(ele);
    let current = null;
    if (this.head) {
      this.head = node;
    } else {
      current = this.head;
      while (current.next) {
        current = current.next;
      };
      current.next = node;
    }
    this.length++;
  }
  insert(pos, ele) {
    if (pos > 0 && pos <= this.length) {
      const node = new linkNode(ele);
      let current = this.head;
      let previous = null;
      let index = 0;
      if (pos === 0) {
        this.head = node;
      } else {
        while (index < pos) {
          index++;
          previous = current;
          current = current.next;
        }
        node.next = current;
        previous.next = node;
      }
      this.length++;
    }
  }
  removeAt(pos) {
    if (pos > -1 && pos < this.length) {
      let current = this.head
      let previous = null
      let index = 0
      if (pos === 0) {
        this.head = current.next
      } else {
        while (index++ < pos) {
          previous = current
          current = current.next
        }
        previous.next = current.next
      }
      this.length--;
      return current.element
    }
  }
  findIndex(element) {
    let current = this.head
    let index = -1
    while (current) {
      if (element === current.element) {
        return index + 1
      }
      index++
      current = current.next
    }
    return -1
  }
  remove(element) {
    const index = this.indexOf(element)
    return this.removeAt(index)
  }
  size() {
    return this.length
  }
}
  • 集合:由一组无序且唯一(即不能重复)的项组成;这个数据结构使用了与有限集合相同的数学概念,但应用在计算机科学的数据结构中。ES6 中已内置了 Set 类型,实现的要点在于查找是否已存在.

  • 字典:以 [键,值]对为数据形态的数据结构,其中键名用来查询特定元素,类似于 Javascript 中的Object。

  • 散列:根据关键码值(Key,value)直接进行访问的数据结构;它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度;这个映射函数叫做散列函数,存放记录的数组叫做散列表。

    • 处理散列表中的冲突:分离链接、线性探查和双散列法。

    • 分离链接法包括为散列表的每一个位置创建一个链表并将元素存储在里面。它是解决冲突的 最简单的方法,但是它在 HashTable 实例之外还需要额外的存储空间。

    • 线性探查:当想向表中某个位置加人一个新元素的时候,如果索引为 index 的位置已经被占据了,就尝试 index+1的位置。如果index+1 的位置也被占据了,就尝试 index+2 的位置,以此类推。

    class HashTable {
     constructor() {
         this.table = []
       }
       // 散列函数
     static loseloseHashCode(key) {
       let hash = 0
       for (let codePoint of key) {
         hash += codePoint.charCodeAt()
       }
       return hash % 37
     }
     // 使用链表处理冲突
     put(key, value) {
       const position = HashTable.loseloseHashCode(key)
       if (this.table[position] === undefined) {
         this.table[position] = new LinkedList()
       }
       this.table[position].append({ key, value })
     }
     get(key) {
       const position = HashTable.loseloseHashCode(key)
       if (this.table[position] === undefined) return undefined
       const getElementValue = node => {
         if (!node && !node.element) return undefined
         if (Object.is(node.element.key, key)) {
           return node.element.value
         } else {
           return getElementValue(node.next)
         }
       }
       return getElementValue(this.table[position].head)
     }
     remove(key) {
       const position = HashTable.loseloseHashCode(key)
       if (this.table[position] === undefined) return undefined
       const getElementValue = node => {
         if (!node && !node.element) return false
         if (Object.is(node.element.key, key)) {
           this.table[position].remove(node.element)
           if (this.table[position].isEmpty) {
             this.table[position] = undefined
           }
           return true
         } else {
           return getElementValue(node.next)
         }
       }
       return getElementValue(this.table[position].head)
     }
     
       // // 使用线性探查
     // put(key, value) {
     //   const position = HashTable.loseloseHashCode(key)
     //   if (this.table[position] === undefined) {
     //     this.table[position] = { key, value }
     //   } else {
     //     let index = position+1;
     //     while (this.table[index] !== undefined) {
     //       index++
     //     }
     //     this.table[index] = { key, value }
     //   }
     // }
    
     // get(key) {
     //   const position = HashTable.loseloseHashCode(key)
     //   const getElementValue = index => {
     //     if (this.table[index] === undefined) return undefined
     //     if (Object.is(this.table[index].key, key)) {
     //       return this.table[index].value
     //     } else {
     //       return getElementValue(index + 1)
     //     }
     //   }
     //   return getElementValue(position)
     // }
    }
    
  • 树:由 n(n>=1)个有限节点组成一个具有层次关系的集合;把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的,基本呈一对多关系,树也可以看做是图的特殊形式。

    • 节点

      • 根节点

      • 内部节点:非根节点、且有子节点的节点

      • 外部节点/页节点:无子节点的节点

    • 子树:就是大大小小节点组成的树

    • 深度:节点到根节点的节点数量

    • 高度:树的高度取决于所有节点深度中的最大值

    • 层级:也可以按照节点级别来分层

二叉树中的节点最多只能有两个子节点:一个是左侧子节点,另一个是右侧子节点。这些定 义有助于我们写出更高效的向/从树中插人、查找和删除节点的算法。二叉树在计算机科学中的 应用非常广泛。
二叉搜索树(BST)是二叉树的一种,但是它只允许你在左侧节点存储(比父节点)小的值, 在右侧节点存储(比父节点)大(或者等于)的值。

class binNode {
    constructor(key) {
        this.key = key
        this.left = null
        this.right = null
    }
}
class BinarySearchTree {
    constructor() {
        this.root = null
    }
    insert(key) {
        const newNode = new binNode(key)
        const insertNode = (node, newNode) => {
            if (newNode.key < node.key) {
                if (node.left === null) {
                    node.left = newNode
                } else {
                    insertNode(node.left, newNode)
                }
            } else {
                if (node.right === null) {
                    node.right = newNode
                } else {
                    insertNode(node.right, newNode)
                }
            }
        }
        if (!this.root) {
            this.root = newNode
        } else {
            insertNode(this.root, newNode)
        }
    }
}
  • 图:图是网络结构的抽象模型;图是一组由边连接的节点(顶点);任何二元关系都可以用图来表示,常见的比如:道路图、关系图,呈多对多关系。


算法

  • 排序算法

    • 冒泡排序:比较任何两个相邻的项,如果第一个比第二个大,则交换它们;元素项向上移动至正确的顺序,好似气泡上升至表面一般,因此得名。

    • 选择排序:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,以此循环,直至排序完毕。

    • 插入排序:将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,此算法适用于少量数据的排序,时间复杂度为 O(n^2)。

    • 归并排序:将原始序列切分成较小的序列,只到每个小序列无法再切分,然后执行合并,即将小序列归并成大的序列,合并过程进行比较排序,只到最后只有一个排序完毕的大序列,时间复杂度为 O(n log n)。

    • 快速排序:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行上述递归排序,以此达到整个数据变成有序序列,时间复杂度为 O(n log n)。
      搜索算法

    • 顺序搜索:让目标元素与列表中的每一个元素逐个比较,直到找出与给定元素相同的元素为止,缺点是效率低下。

    • 二分搜索:在一个有序列表,以中间值为基准拆分为两个子列表,拿目标元素与中间值作比较从而再在目标的子列表中递归此方法,直至找到目标元素。

  • 贪心算法:在对问题求解时,不考虑全局,总是做出局部最优解的方法。

  • 动态规划:在对问题求解时,由以求出的局部最优解来推导全局最优解。

  • 复杂度概念:一个方法在执行的整个生命周期,所需要占用的资源,主要包括:时间资源、空间资源。

参考:
数据结构
前端数据结构


http://www.niftyadmin.cn/n/1119851.html

相关文章

Tomcat 安装为服务后台自动启用

1.首先设置环境变量 2.Java_home 3.path 4.在运行输入cmd命令后 输入tomcat所安装的路径文件中的service.bat直接拖进来即可 此时要注意 如果服务器用户没有管理员权限的用户一定要运行命令时使用管理员权限进行 否则 安装时一直提示安装失败。 5.安装成功效果图所示 6.进入服务…

mysql查看当前所在库_MySQL查看当前数据库

(1)在MySQL下查看当前使用的是哪个数据库&#xff0c;有三种方式用select database()语句mysql> select database();------------| database() |------------| test |------------1 row in set (0.00 sec)从查询结果中可以看出&#xff0c;当前用的是test数据库(2)用show ta…

wangzhi

https://www.cnblogs.com/NotAnEmpty/p/5241902.html转载于:https://www.cnblogs.com/wrnsweet/p/8688671.html

larave自定义公共函数的创建

原文地址&#xff1a;http://blog.csdn.net/qq_38125058/article/details/76862151 公共函数&#xff0c;简单来说就是在任何地方都可以直接使用这个函数。简单介绍两种实现方法。 注&#xff1a;5.5已经不存在autoload.php这个文件了&#xff0c;可以用第二种方法实现。 首…

Day9 进程同步锁 进程队列 进程池 生产消费模型 进程池 paramike模块...

进程同步锁&#xff1a; 当运行程序的时候&#xff0c;有可能你的程序同时开多个进程&#xff0c;开进程的时候会将多个执行结果打印出来&#xff0c;这样的话打印的信息都是错乱的&#xff0c;怎么保证打印信息是有序的呢&#xff1f; 其实也就是相当于让进程独享资源。 1 fro…

vue 引入canvas_Vue中使用canvas方法总结

下面就是小编带给大家的Vue中怎么使用canvas方法操作&#xff0c;希望能够给你们带来一定的帮助&#xff0c;谢谢大家的观看。1、如果数组中都是canvas对象, vue如何能吧canvas对象渲染到页面。v-html只能渲染出一个字符串, 没办法像appendChild那样插入canvas对象。2、项目架构…

反射,方法的调用

2019独角兽企业重金招聘Python工程师标准>>> 一、方法对象&#xff0c;Method 类型的对象 (1)获得方法对象数组 //Method[] m class.getMethods()方法获取是该类的所有public方法&#xff0c;包括从父类继承的方法&#xff1b; //Method[] m class.getDeclaredMetho…

TCP报文大小

链路层&#xff08;二层&#xff09;MTU最大传输单元&#xff1a;1500KByte。每个以太网帧64bytes-1518bytes&#xff0c;减去帧头&#xff08;DMAC目的MAC地址48bit6BytesSMAC源MAC地址48bit6BytesType域2bytes&#xff09;14Bytes和帧尾CRC校验部分4Bytes&#xff0c;即为MTU…