js數據結構和算法(2)-隊列&基數排序

2 隊列

隊列是一種隊列,不一樣的是隊列只能從隊尾插入元素,在隊首刪除元素,隊列用於存儲按順序排列的數據,先進先去javascript

2.1 隊列的方法和屬性

隊列的方法和屬性 含義
enqueue(方法) 在隊列尾部插入一個元素
dequeue(方法) 在隊列頭部刪除一個元素
front(方法) 返回隊列頭部的元素
back(方法) 返回隊列尾部的元素
toString(方法) 返回隊列的字符串形式
empty(方法) 判斷一個隊列是否爲空
length(屬性) 返回隊列的長度

2.2 實現一個隊列

class Queue {
  constructor() {
    this.dataStore = []
  }
  enqueue(ele) {
    this.dataStore.push(ele)
  }
  dequeue() {
    return this.dataStore.shift()
  }
  front() {
    return this.dataStore[0]
  }
  back() {
    return this.dataStore[this.dataStore.length - 1]
  }
  toString() {
    return this.dataStore.join(' ')
  }
  empty() {
    return this.dataStore.length == 0
  }
}

// 測試
let q = new Queue()
q.enqueue('a')
q.enqueue('b')
q.enqueue('c')
console.log(q.toString()) // a b c
q.dequeue()
console.log(q.toString()) // b c
console.log('front:', q.front()) // front: b
console.log('back:', q.back()) // back: c

複製代碼

2.3 基數排序

基數排序又叫桶排序,是一種數值排序的方法。從低位開始將待排序的數按照這一位的值放到相應的編號爲0~9的桶中。等到低位排完獲得一個子序列,再將這個序列按照次低位的大小進入相應的桶中,一直排到最高位爲止,數組排序完成。java

假設有如下一串數字,咱們對起進行基數排序.基數排序要求數值的位數必須相同,不一樣的話,數值左邊補0便可git

43 21 35 24 76 52 23 44數組

2.3.1 按照個位數把數值放入不一樣的桶中

基數 數值 數值
0
1 21
2 52
3 43 23
4 24 44
5 35
6 76
7
8
9

從上到下獲得一個排序後的數值。 21 52 43 23 24 44 35 76學習

我的理解:個位數排序的意義是保證了若是2個數值十位數相同,那麼他們確定個數數值小的數在前面測試

2.3.2 按照十位數把數值放入不一樣的桶中

基數 數值 數值 數值
0
1
2 21 23 24
3 35
4 43 44
5 52
6
7 76
8
9

從上到下獲得排序後的數值:21 23 24 35 43 44 52 76ui

21 52 43 23 24 44 35 76 通過基數排序後結果以下 21 23 24 35 43 44 52 76this

自此咱們使用基數排序法完成了對數值的排序spa

2.3.3 基數排序的類型

基數排序有2種類型code

  • LSD-從低位向高位排
  • MSD-從高位向低位排

兩個排序方法原理都如出一轍,LSD 適用於數字位數比較少的數值排序,MSD適用於數值位數比較多的數值排序

2.4 使用隊列實現基數排序

let nums = [43, 21, 35, 24, 76, 52, 23, 44]

function createQueueArr() {
  let queueArr = []
  for (let i = 0; i < 10; i++) {
    queueArr[i] = new Queue()
  }
  return queueArr
}
/** * @description 對數組中的數值按照基數排序的方法分配到不一樣的桶子中 * @param {Array} nums 須要排序的數字組成的數組 * @param {Array} queueArr 10個隊列,至關於10個桶子,分別表明基數0-9 * @param {Number} digit 須要按哪位進行排序,1是對位個位 10對應10位 */
function distribute(nums, queueArr, digit) {
  for (let i = 0; i < nums.length; i++) {
    if (digit == 1) {
      queueArr[nums[i] % 10].enqueue(nums[i])
    } else {
      let tempNum = Math.floor(nums[i] / 10)
      queueArr[tempNum].enqueue(nums[i])
    }
  }
}
/** * @description 對基數排序後數值從上到下進行收集 * @param {Array} queueArr 隊列 */

function collect(queueArr) {
  let tempArr = []
  for (let i = 0; i < queueArr.length; i++) {
    while (!queueArr[i].empty()) {
      tempArr.push(queueArr[i].dequeue())
    }
  }
  return tempArr
}

// 對基數排序進行測試
let queueArr = createQueueArr()
distribute(nums, queueArr, 1)
console.log(queueArr)  // [Queue, Queue, Queue, Queue, Queue, Queue, Queue, Queue, Queue, Queue]

let sortNum1 = collect(queueArr)
console.log(sortNum1) // [21, 52, 43, 23, 24, 44, 35, 76]

let queueArr2 = createQueueArr()
distribute(sortNum1, queueArr2, 10)

let sortNum2 = collect(queueArr2)
console.log(sortNum2) // [21, 23, 24, 35, 43, 44, 52, 76]
複製代碼

測試結果更預想的同樣。說明咱們使用隊列成功實現了基數排序。

2.5 優先隊列

在通常狀況下,從隊列中刪除元素,必定是率先入隊的元素,可是也有一些使用隊列的應用,在刪除元素的時候沒必要遵循先進先出的規則。而是根據優先級大小決定那個先出。好比去銀行辦理業務,vip的人老是比咱們這些屌絲優先。

一個優先隊列跟一個普通的隊列的主要區別是dequeuq方法

優先隊列的dequeue方法以下。

// code 存儲優先級的大小,越小越優先
function dequequ(){
  let entry = 0
  for(let i=0;i<this.dataStore.length;i++){
    if(this.dataStore[i].code<this.dataStore[entry].code){
      entry = i
    }
  }
  return this.dataStore.splice(entry,1)
}
複製代碼

自此關於隊列的全部知識講解完畢。

我的總結:隊列也是列表的一種特殊形式,比較簡單,在生活中的用途彷佛也蠻多的。值得學習下。隊列中涉及到的基數排序方法頗有趣的,也蠻難理解。值得好好研究。

相關文章
相關標籤/搜索