前端搞算法,你要会栈,队列,链表,打包给你

315 阅读4分钟

前端算法不好,有时候不是数学思路不好,而是js的基础数据结构不清晰,不知道何时应该使用哪些方便的工具。

我系统的总结了一些前端的数据结构,应该可以帮助大家。

栈是一种后进先出(LIFO,Last-In-First-Out)的结构,数据的插入与删除只在一个地方发生。

ECMAScript给array 提供方法来模仿“栈”,推入(插入,push)和弹出(删除,pop),来实现类似栈的行为。

栈的示意图

let colors = new Array();
let count = colors.push('red','black') //把red,black加入数组,返回数组的length为2

count = colors.push('green') //把green加入数组,返回数组的length为3

let item = colors.pop() // 退出最后一项,返回对应的item为green

队列

队列是一种先进先出(FIFO,First-In-First-Out)的结构。在列表末尾添加数据,在列表开头获取数据。

ECMAScript给array 提供方法来模仿“队列”,入列(插入,pop)和出列(删除,shift),来实现类似栈的行为。

队列的示意图

let colors = new Array();
let count = colors.push('red','black') //把red,black加入数组,返回数组的length为2

count = colors.push('green') //把green加入数组,返回数组的length为3

let item = colors.shift() // 退出第一项,返回对应的item为red

如果是反向队列怎么办?

ECMAScript给array 提供方法unshift(使用方法同push),可以向数组开头插入数据。同时可以使用pop方法来从队尾删除数据。 反向队列的示意图

let colors = new Array();
let count = colors.unshift('red','black') //把red,black加入数组,返回数组的length为2

count = colors.unshift('green') //把green加入数组,返回数组的length为3

let item = colors.pop() // 退出第一项,返回对应的item为black

链表

链表是什么

百度百科解释: 链表是一种非连续,非顺序的存储结构。数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

链表示意图

js实现参考leetcode

设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val 和 next。val 是当前节点的值,next 是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性 prev 以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。

在链表类中实现这些功能:

get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。
addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val  的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。
 

示例:

MyLinkedList linkedList = new MyLinkedList();
linkedList.addAtHead(1);
linkedList.addAtTail(3);
linkedList.addAtIndex(1,2);   //链表变为1-> 2-> 3
linkedList.get(1);            //返回2
linkedList.deleteAtIndex(1);  //现在链表是1-> 3
linkedList.get(1);            //返回3
/**
 * Initialize your data structure here.
 */
var MyLinkedList = function() {
  this.head=null
  this.rear=null
  this.len=0
};
function ListNode(val) {
  this.val = val;
  this.next = null;
}
/**
 * Get the value of the index-th node in the linked list. If the index is invalid, return -1. 
 * @param {number} index
 * @return {number}
 */
MyLinkedList.prototype.get = function(index) {
  if(index<0||index>this.len-1)
    return -1
  var node=this.head
  while(index-->0){
    if(node.next==null)
      return -1
    node=node.next
  }
  return node.val
};

/**
 * Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. 
 * @param {number} val
 * @return {void}
 */
MyLinkedList.prototype.addAtHead = function(val) {
  var node=new ListNode(val)
  if(this.head==null)
    this.rear=node
  else
    node.next=this.head
  this.head=node
  this.len++
};

/**
 * Append a node of value val to the last element of the linked list. 
 * @param {number} val
 * @return {void}
 */
MyLinkedList.prototype.addAtTail = function(val) {
  var node=new ListNode(val)
  if(this.head==null)
    this.head=node
  else
    this.rear.next=node
  this.rear=node
  this.len++
};

/**
 * Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. 
 * @param {number} index 
 * @param {number} val
 * @return {void}
 */
MyLinkedList.prototype.addAtIndex = function(index, val) {
  if(index<=0)
    return this.addAtHead(val)
  if(this.len<index)
    return
  if(index==this.len)
    return this.addAtTail(val)
  var node=this.head
  while(index-->1){
    node=node.next
  }
    
  var newnode=new ListNode(val)
  newnode.next=node.next
  node.next=newnode
  this.len++
};

/**
 * Delete the index-th node in the linked list, if the index is valid. 
 * @param {number} index
 * @return {void}
 */
MyLinkedList.prototype.deleteAtIndex = function(index) {
  if(index<0||index>this.len-1||this.len==0)
    return
  if(index==0){
    this.head=this.head.next
    this.len--
    return
  }

  var node=this.head
  var myindex=index
  while(index-->1){
    node=node.next
  }
  if(myindex==(this.len-1)){
    this.rear=node
  }
  node.next=node.next.next
  this.len--
};

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * var obj = new MyLinkedList()
 * var param_1 = obj.get(index)
 * obj.addAtHead(val)
 * obj.addAtTail(val)
 * obj.addAtIndex(index,val)
 * obj.deleteAtIndex(index)
 */