class Heap { constructor (str) { let map = new Map() str.split('').forEach(item => { if (map.has(item)) { map.set(item, map.get(item) + 1) } else { map.set(item, 1) } }) this.map = map this.data = Array.from(map.values()) } sort () { let iArr = this.data let n = iArr.length if (n <= 1) { return iArr } else { // 循環是爲了遍歷每個可能要調整的節點,maxHeapify內部遞歸是爲了回覆被破壞的堆 for (let i = Math.floor(n / 2); i >= 0; i--) { Heap.maxHeapify(iArr, i, n) } for (let j = 0; j < n; j++) { Heap.swap(iArr, 0, n - 1 - j) Heap.maxHeapify(iArr, 0, n - 1 - j - 1) } return iArr } } toString () { let arr = this.sort() let str = [] while (arr.length) { // 由於這裏因此要刪除遍歷過的k let top = arr.pop() for (let [k, v] of this.map) { if (v === top) { str.push(k.repeat(v)) this.map.delete(k) break } } } return str.join('') } static swap (arr, a, b) { if (a === b) { return '' } // 交換 let c = arr[a] arr[a] = arr[b] arr[b] = c } // 構建最大堆 static maxHeapify (Arr, i, size) { // 左節點 let l = i * 2 + 1 // 右節點 let r = i * 2 + 2 let largest = i // 父節點和左節點l做比較獲取最大 if (l <= size && Arr[l] > Arr[largest]) { largest = l } // 右節點額最大值比較 if (r <= size && Arr[r] > Arr[largest]) { largest = r } if (largest !== i) { Heap.swap(Arr, i, largest) Heap.maxHeapify(Arr, largest, size) } } } export default Heap