1. 程式人生 > >學習JavaScript數據結構與算法 (二)

學習JavaScript數據結構與算法 (二)

學習 bug block con 大於 第五章 lock truct 保存

  • 學習JavaScript數據結構與算法 的筆記
  • 包含第四章隊列, 第五章鏈表
  • 本人所有文章首發在博客園: http://www.cnblogs.com/zhangrunhao/

04隊列

實現基本隊列

class Queue {
  constructor () {
    this.items = []
  }
  enqueue(item) {
    return this.items.push(item)
  }
  dequeque() {
    return this.items.shift()
  }
  font() {
    return this.items[0]
  }
  isEmpty() {
    return this.items.length === 0
  }
  clear() {
    return this.items = []
  }
  size() {
    return this.items.length
  }
}

實現具有優先級的隊列


class QueueElement {
  constructor(element, priority) {
    this.element = element
    this.priority = priority
  }
}

class priorityQueue extends Queue {
  enqueue(element, priority) {
    var item = new QueueElement(element, priority)
    if (this.isEmpty()) { // 隊列為空, 直接入隊
      this.items.push(item)
    } else {
      var added = false // 是否添加過的標誌位
      this.items.forEach((val, index, arr) => {
        // 此處決定最小優先隊列, 還是最大優先隊列
        // 如果我們添加的元素的優先級剛剛好大於遍歷到的那個元素
        // 就插入到這個元素的位置
        // 也能保證在相同優先級下面, 的隊尾
        if (item.priority > val.priority && !added) {
          arr.splice(index, 0, item)
          added = true
        }
      })
      // 如果優先級小於全部的元素, 就放到隊尾
      !added && this.items.push(item)
    }
  }
}

var priQue = new priorityQueue
priQue.enqueue(‘a‘, 1)
priQue.enqueue(‘a‘, 1)
priQue.enqueue(‘b‘, 5)
priQue.enqueue(‘c‘, 3)
priQue.enqueue(‘d‘, 7)
debugger;

循環隊列 模仿擊鼓傳花

function hotPotato(nameList) {
  var queue = new Queue
  nameList.forEach((val) => {
    queue.enqueue(val)
  })
  while(queue.size() > 1) {
    var num = Math.floor(Math.random() * 10 + 1)
    debugger;
    for(let i = 0; i < num; i++) {
      queue.enqueue(queue.dequeque())
    }
    var outer = queue.dequeque()
    console.log(`${outer}被淘汰了`)
  }
  var winner = queue.dequeque()
  console.log(`${winner}勝利`)
  return winner
}

var nameList = [‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘]
hotPotato(nameList)

05鏈表

  • 數組很容易根據指針找到固定元素
  • 鏈表尋找某個元素, 只能從頭遍歷

單項鏈表

class Node {
  constructor(element) {
    this.element = element
    this.next = null
  }
}

class LinkDist {
  constructor() {
    this.length = 0
    this.head = null
  }
  append(element) {
    return append.call(this, element)
  }
  search(postion, cb) {
    return search.call(this, postion, cb)
  }
  insert(position, element) {
    return insert.call(this, position, element)
  }
  removeAt(postion) {
    return removeAt.call(this, postion)
  }
  indexOf(element, cb) {
    var cur = this.head, pre = null
    while(cur.next) {
      if (cur.element === element) {
        cb.call(this, pre, cur)
      }
      pre = cur
      cur = cur.next
    }
    return null
  }
  remove(element) {
    this.indexOf(element, (pre, cur) => {
      if (pre && cur) {
        pre.next = cur.next
        this.length--
      } else if (cur) {
        this.head = cur.next
        this.length--
      }
    })
  }
  isEmpty() {
    return this.length === 0
  }
  size() {
    return this.length
  }
  toString() {
    var res = ‘‘, cur = this.head, index = 0
    while (index++ < this.length) {
      res += cur.element
      cur = cur.next
    }
    return res
  }
  getHead() {
    return this.head
  }
}

function append(element) {
  var node = new Node(element)
  var cur = null
  if (this.head === null) {
    this.head = node
  } else {
    cur = this.head // 先指向當前的第一個元素
    while(cur.next) { // 只要有next就往下叠代
      cur = cur.next
    }
    cur.next = node // 沒有next的時候, 保存下next指向node
  }
  this.length++
}
function search(position, cb) {
  if (position > -1 && position < this.length) {
    var cur = this.head, pre = null, index = 0
    if (position === 0) {
      cb.call(this, null, cur)
    } else {
      while (index++ < position) {
        pre = cur
        cur = cur.next
      }
      cb.call(this, pre, cur)
    }
    return cur
  } else {
    cb.call(this, null, null)
    return null
  }
}
function removeAt(position) {
  return this.search(position, (pre, cur) => {
    if (pre) {
      pre.next = cur.next
      this.length--
    } else if (cur) {
      this.head = cur.next
      this.length--
    } else {
      throw new Error(‘未找到元素‘)
      return false
    }
  })
}
function insert(position, element) {
  this.search(position, (pre, cur) => {
    if (pre && cur) {
      // 除第一項以外的
      pre.next = new Node(element)
      pre.next.next = cur
    } else if (cur) {
      // 第一項
      this.head = new Node(element)
      this.head.next = cur
    } else {
      throw new Error(‘元素並不存在‘)
    }
    this.length++
  })
}

var list = new LinkDist
list.append(15)
list.append(10)
list.append(5)
list.insert(1, 9)
list.remove(10)
var res = list.toString()

單項鏈表反轉

學習JavaScript數據結構與算法 (二)