【從蛋殼到滿天飛】JS 數據結構解析和算法實現,所有文章大概的內容以下: Arrays(數組)、Stacks(棧)、Queues(隊列)、LinkedList(鏈表)、Recursion(遞歸思想)、BinarySearchTree(二分搜索樹)、Set(集合)、Map(映射)、Heap(堆)、PriorityQueue(優先隊列)、SegmentTree(線段樹)、Trie(字典樹)、UnionFind(並查集)、AVLTree(AVL 平衡樹)、RedBlackTree(紅黑平衡樹)、HashTable(哈希表)html
源代碼有三個:ES6(單個單個的 class 類型的 js 文件) | JS + HTML(一個 js 配合一個 html)| JAVA (一個一個的工程)前端
所有源代碼已上傳 github,點擊我吧,光看文章可以掌握兩成,動手敲代碼、動腦思考、畫圖才能夠掌握八成。git
本文章適合 對數據結構想了解而且感興趣的人羣,文章風格一如既往如此,就以爲手機上看起來比較方便,這樣顯得比較有條理,整理這些筆記加源碼,時間跨度也算將近半年時間了,但願對想學習數據結構的人或者正在學習數據結構的人羣有幫助。github
無處不在的 Undo 操做(撤銷)面試
程序調用的系統棧算法
function A () {
1 ...;
2 B();
3 ...;
}
function B () {
1 ...;
2 C();
3 ...;
}
function C () {
1 ...;
2 ...;
3 ...;
}
複製代碼
系統棧記錄的過程是:編程
A2
會被放入系統棧中,系統棧中顯示:[A2]
,[A2, B2]
,[A2]
,[]
,2 和 3 中解釋的原理 就是系統棧最神奇的地方數組
棧雖然是一個很是簡單的數據結構性能優化
MyStack
void push(e)
:入棧E pop()
:出棧E peek()
:查看位於棧頂位置的元素int getSize()
:獲取棧中實際元素的個數boolean isEmpty()
:棧是否爲空MyStack
void push(e)
:O(1) 均攤E pop()
:O(1) 均攤E peek()
:O(1)int getSize()
:O(1)boolean isEmpty()
:O(1)(class: MyArray, class: MyStack, class: Main)
網絡
MyArray
class MyArray {
// 構造函數,傳入數組的容量capacity構造Array 默認數組的容量capacity=10
constructor(capacity = 10) {
this.data = new Array(capacity);
this.size = 0;
}
// 獲取數組中的元素實際個數
getSize() {
return this.size;
}
// 獲取數組的容量
getCapacity() {
return this.data.length;
}
// 判斷數組是否爲空
isEmpty() {
return this.size === 0;
}
// 給數組擴容
resize(capacity) {
let newArray = new Array(capacity);
for (var i = 0; i < this.size; i++) {
newArray[i] = this.data[i];
}
// let index = this.size - 1;
// while (index > -1) {
// newArray[index] = this.data[index];
// index --;
// }
this.data = newArray;
}
// 在指定索引處插入元素
insert(index, element) {
// 先判斷數組是否已滿
if (this.size == this.getCapacity()) {
// throw new Error("add error. Array is full.");
this.resize(this.size * 2);
}
// 而後判斷索引是否符合要求
if (index < 0 || index > this.size) {
throw new Error(
'insert error. require index < 0 or index > size.'
);
}
// 最後 將指定索引處騰出來
// 從指定索引處開始,全部數組元素所有日後移動一位
// 從後往前移動
for (let i = this.size - 1; i >= index; i--) {
this.data[i + 1] = this.data[i];
}
// 在指定索引處插入元素
this.data[index] = element;
// 維護一下size
this.size++;
}
// 擴展 在數組最前面插入一個元素
unshift(element) {
this.insert(0, element);
}
// 擴展 在數組最後面插入一個元素
push(element) {
this.insert(this.size, element);
}
// 其實在數組中添加元素 就至關於在數組最後面插入一個元素
add(element) {
if (this.size == this.getCapacity()) {
// throw new Error("add error. Array is full.");
this.resize(this.size * 2);
}
// size其實指向的是 當前數組最後一個元素的 後一個位置的索引。
this.data[this.size] = element;
// 維護size
this.size++;
}
// get
get(index) {
// 不能訪問沒有存放元素的位置
if (index < 0 || index >= this.size) {
throw new Error('get error. index < 0 or index >= size.');
}
return this.data[index];
}
// 擴展: 獲取數組中第一個元素
getFirst() {
return this.get(0);
}
// 擴展: 獲取數組中最後一個元素
getLast() {
return this.get(this.size - 1);
}
// set
set(index, newElement) {
// 不能修改沒有存放元素的位置
if (index < 0 || index >= this.size) {
throw new Error('set error. index < 0 or index >= size.');
}
this.data[index] = newElement;
}
// contain
contain(element) {
for (var i = 0; i < this.size; i++) {
if (this.data[i] === element) {
return true;
}
}
return false;
}
// find
find(element) {
for (var i = 0; i < this.size; i++) {
if (this.data[i] === element) {
return i;
}
}
return -1;
}
// findAll
findAll(element) {
// 建立一個自定義數組來存取這些 元素的索引
let myarray = new MyArray(this.size);
for (var i = 0; i < this.size; i++) {
if (this.data[i] === element) {
myarray.push(i);
}
}
// 返回這個自定義數組
return myarray;
}
// 刪除指定索引處的元素
remove(index) {
// 索引合法性驗證
if (index < 0 || index >= this.size) {
throw new Error('remove error. index < 0 or index >= size.');
}
// 暫存即將要被刪除的元素
let element = this.data[index];
// 後面的元素覆蓋前面的元素
for (let i = index; i < this.size - 1; i++) {
this.data[i] = this.data[i + 1];
}
this.size--;
this.data[this.size] = null;
// 若是size 爲容量的四分之一時 就能夠縮容了
// 防止複雜度震盪
if (Math.floor(this.getCapacity() / 4) === this.size) {
// 縮容一半
this.resize(Math.floor(this.getCapacity() / 2));
}
return element;
}
// 擴展:刪除數組中第一個元素
shift() {
return this.remove(0);
}
// 擴展: 刪除數組中最後一個元素
pop() {
return this.remove(this.size - 1);
}
// 擴展: 根據元素來進行刪除
removeElement(element) {
let index = this.find(element);
if (index !== -1) {
this.remove(index);
}
}
// 擴展: 根據元素來刪除全部元素
removeAllElement(element) {
let index = this.find(element);
while (index != -1) {
this.remove(index);
index = this.find(element);
}
// let indexArray = this.findAll(element);
// let cur, index = 0;
// for (var i = 0; i < indexArray.getSize(); i++) {
// // 每刪除一個元素 原數組中就少一個元素,
// // 索引數組中的索引值是按照大小順序排列的,
// // 因此 這個cur記錄的是 原數組元素索引的偏移量
// // 只有這樣纔可以正確的刪除元素。
// index = indexArray.get(i) - cur++;
// this.remove(index);
// }
}
// @Override toString 2018-10-17-jwl
toString() {
let arrInfo = `Array: size = ${this.getSize()},capacity = ${this.getCapacity()},\n`;
arrInfo += `data = [`;
for (var i = 0; i < this.size - 1; i++) {
arrInfo += `${this.data[i]}, `;
}
if (!this.isEmpty()) {
arrInfo += `${this.data[this.size - 1]}`;
}
arrInfo += `]`;
// 在頁面上展現
document.body.innerHTML += `${arrInfo}<br /><br /> `;
return arrInfo;
}
}
複製代碼
MyStack
class MyStack {
constructor(capacity = 10) {
this.myArray = new MyArray(capacity);
}
// 入棧
push(element) {
this.myArray.push(element);
}
// 出棧
pop() {
return this.myArray.pop();
}
// 查看棧頂的元素
peek() {
return this.myArray.getLast();
}
// 棧中實際元素的個數
getSize() {
return this.myArray.getSize();
}
// 棧是否爲空
isEmpty() {
return this.myArray.isEmpty();
}
// 查看棧的容量
getCapacity() {
return this.myArray.getCapacity();
}
// @Override toString 2018-10-20-jwl
toString() {
let arrInfo = `Stack: size = ${this.getSize()},capacity = ${this.getCapacity()},\n`;
arrInfo += `data = [`;
for (var i = 0; i < this.myArray.size - 1; i++) {
arrInfo += `${this.myArray.data[i]}, `;
}
if (!this.isEmpty()) {
arrInfo += `${this.myArray.data[this.myArray.size - 1]}`;
}
arrInfo += `] stack top is right!`;
// 在頁面上展現
document.body.innerHTML += `${arrInfo}<br /><br /> `;
return arrInfo;
}
}
複製代碼
Main
class Main {
constructor() {
this.alterLine('MyStack Area');
let ms = new MyStack(10);
for (let i = 1; i <= 10; i++) {
ms.push(i);
console.log(ms.toString());
}
console.log(ms.peek());
this.show(ms.peek());
while (!ms.isEmpty()) {
console.log(ms.toString());
ms.pop();
}
}
// 將內容顯示在頁面上
show(content) {
document.body.innerHTML += `${content}<br /><br />`;
}
// 展現分割線
alterLine(title) {
let line = `--------------------${title}----------------------`;
console.log(line);
document.body.innerHTML += `${line}<br /><br />`;
}
}
window.onload = function() {
// 執行主函數
new Main();
};
複製代碼
括號匹配-編譯器
編譯器是如何檢查括號匹配的問題?
能夠經過解答 Leetcode 中的一個問題,
leetcode.com
,leetcode-cn.com
leetcode.com
與leetcode-cn.com
的區別
leetcode-cn.com
支持中文,leetcode-cn.com
的題目數量沒有英文版的多。leetcode-cn.com
的探索欄目的內容沒有英文版的多。leetcode-cn.com
中的題目沒有社區討論功能,但英文版的有。leetcode 中第二十號題目:有效的括號
{ [ ( ) ] }
,class Solution {
isValid(s) {
// leetcode 20. 有效的括號
/** * @param {string} s * @return {boolean} */
var isValid = function(s) {
let stack = [];
// 以遍歷的方式進行匹配操做
for (let i = 0; i < s.length; i++) {
// 是不是正括號
switch (s[i]) {
case '{':
case '[':
case '(':
stack.push(s[i]);
break;
default:
break;
}
// 是不是反括號
switch (s[i]) {
case '}':
if (stack.length === 0 || stack.pop() !== '{') {
console.log('valid error. not parentheses. in');
return false;
}
break;
case ']':
if (stack.length === 0 || stack.pop() !== '[') {
console.log('valid error. not parentheses. in');
return false;
}
break;
case ')':
if (stack.length === 0 || stack.pop() !== '(') {
console.log('valid error. not parentheses. in');
return false;
}
break;
default:
break;
}
}
// 是否所有匹配成功
if (stack.length === 0) {
return true;
} else {
console.log('valid error. not parentheses. out');
return false;
}
};
return isValid(s);
}
}
複製代碼
class Main {
constructor() {
// this.alterLine("MyStack Area");
// let ms = new MyStack(10);
// for (let i = 1; i <= 10 ; i++) {
// ms.push(i);
// console.log(ms.toString());
// }
// console.log(ms.peek());
// this.show(ms.peek());
// while (!ms.isEmpty()) {
// console.log(ms.toString());
// ms.pop();
// }
this.alterLine('leetcode 20. 有效的括號');
let s = new Solution();
this.show(s.isValid('{ [ ( ) ] }'));
this.show(s.isValid(' [ ( ] ) '));
}
// 將內容顯示在頁面上
show(content) {
document.body.innerHTML += `${content}<br /><br />`;
}
// 展現分割線
alterLine(title) {
let line = `--------------------${title}----------------------`;
console.log(line);
document.body.innerHTML += `${line}<br /><br />`;
}
}
window.onload = function() {
// 執行主函數
new Main();
};
複製代碼
leetcode 是一個很是好的準備面試的一個平臺
若是你想使用你本身寫的類,
Queue
void enqueue(E)
:入隊E dequeue()
:出隊E getFront()
:查看隊首的元素int getSize()
:獲取隊列中的實際元素大小boolean isEmpty()
:獲取隊列是否爲空的 bool 值class: MyArray, class: MyQueue, class: Main)
MyArray
class MyArray {
// 構造函數,傳入數組的容量capacity構造Array 默認數組的容量capacity=10
constructor(capacity = 10) {
this.data = new Array(capacity);
this.size = 0;
}
// 獲取數組中的元素實際個數
getSize() {
return this.size;
}
// 獲取數組的容量
getCapacity() {
return this.data.length;
}
// 判斷數組是否爲空
isEmpty() {
return this.size === 0;
}
// 給數組擴容
resize(capacity) {
let newArray = new Array(capacity);
for (var i = 0; i < this.size; i++) {
newArray[i] = this.data[i];
}
// let index = this.size - 1;
// while (index > -1) {
// newArray[index] = this.data[index];
// index --;
// }
this.data = newArray;
}
// 在指定索引處插入元素
insert(index, element) {
// 先判斷數組是否已滿
if (this.size == this.getCapacity()) {
// throw new Error("add error. Array is full.");
this.resize(this.size * 2);
}
// 而後判斷索引是否符合要求
if (index < 0 || index > this.size) {
throw new Error(
'insert error. require index < 0 or index > size.'
);
}
// 最後 將指定索引處騰出來
// 從指定索引處開始,全部數組元素所有日後移動一位
// 從後往前移動
for (let i = this.size - 1; i >= index; i--) {
this.data[i + 1] = this.data[i];
}
// 在指定索引處插入元素
this.data[index] = element;
// 維護一下size
this.size++;
}
// 擴展 在數組最前面插入一個元素
unshift(element) {
this.insert(0, element);
}
// 擴展 在數組最後面插入一個元素
push(element) {
this.insert(this.size, element);
}
// 其實在數組中添加元素 就至關於在數組最後面插入一個元素
add(element) {
if (this.size == this.getCapacity()) {
// throw new Error("add error. Array is full.");
this.resize(this.size * 2);
}
// size其實指向的是 當前數組最後一個元素的 後一個位置的索引。
this.data[this.size] = element;
// 維護size
this.size++;
}
// get
get(index) {
// 不能訪問沒有存放元素的位置
if (index < 0 || index >= this.size) {
throw new Error('get error. index < 0 or index >= size.');
}
return this.data[index];
}
// 擴展: 獲取數組中第一個元素
getFirst() {
return this.get(0);
}
// 擴展: 獲取數組中最後一個元素
getLast() {
return this.get(this.size - 1);
}
// set
set(index, newElement) {
// 不能修改沒有存放元素的位置
if (index < 0 || index >= this.size) {
throw new Error('set error. index < 0 or index >= size.');
}
this.data[index] = newElement;
}
// contain
contain(element) {
for (var i = 0; i < this.size; i++) {
if (this.data[i] === element) {
return true;
}
}
return false;
}
// find
find(element) {
for (var i = 0; i < this.size; i++) {
if (this.data[i] === element) {
return i;
}
}
return -1;
}
// findAll
findAll(element) {
// 建立一個自定義數組來存取這些 元素的索引
let myarray = new MyArray(this.size);
for (var i = 0; i < this.size; i++) {
if (this.data[i] === element) {
myarray.push(i);
}
}
// 返回這個自定義數組
return myarray;
}
// 刪除指定索引處的元素
remove(index) {
// 索引合法性驗證
if (index < 0 || index >= this.size) {
throw new Error('remove error. index < 0 or index >= size.');
}
// 暫存即將要被刪除的元素
let element = this.data[index];
// 後面的元素覆蓋前面的元素
for (let i = index; i < this.size - 1; i++) {
this.data[i] = this.data[i + 1];
}
this.size--;
this.data[this.size] = null;
// 若是size 爲容量的四分之一時 就能夠縮容了
// 防止複雜度震盪
if (Math.floor(this.getCapacity() / 4) === this.size) {
// 縮容一半
this.resize(Math.floor(this.getCapacity() / 2));
}
return element;
}
// 擴展:刪除數組中第一個元素
shift() {
return this.remove(0);
}
// 擴展: 刪除數組中最後一個元素
pop() {
return this.remove(this.size - 1);
}
// 擴展: 根據元素來進行刪除
removeElement(element) {
let index = this.find(element);
if (index !== -1) {
this.remove(index);
}
}
// 擴展: 根據元素來刪除全部元素
removeAllElement(element) {
let index = this.find(element);
while (index != -1) {
this.remove(index);
index = this.find(element);
}
// let indexArray = this.findAll(element);
// let cur, index = 0;
// for (var i = 0; i < indexArray.getSize(); i++) {
// // 每刪除一個元素 原數組中就少一個元素,
// // 索引數組中的索引值是按照大小順序排列的,
// // 因此 這個cur記錄的是 原數組元素索引的偏移量
// // 只有這樣纔可以正確的刪除元素。
// index = indexArray.get(i) - cur++;
// this.remove(index);
// }
}
// @Override toString 2018-10-17-jwl
toString() {
let arrInfo = `Array: size = ${this.getSize()},capacity = ${this.getCapacity()},\n`;
arrInfo += `data = [`;
for (var i = 0; i < this.size - 1; i++) {
arrInfo += `${this.data[i]}, `;
}
if (!this.isEmpty()) {
arrInfo += `${this.data[this.size - 1]}`;
}
arrInfo += `]`;
// 在頁面上展現
document.body.innerHTML += `${arrInfo}<br /><br /> `;
return arrInfo;
}
}
複製代碼
MyQueue
class MyQueue {
constructor(capacity = 10) {
this.myArray = new MyArray(capacity);
}
// 入隊
enqueue(element) {
this.myArray.push(element);
}
// 出隊
dequeue() {
return this.myArray.shift();
}
// 查看隊首的元素
getFront() {
return this.myArray.getFirst();
}
// 查看隊列中實際元素的個數
getSize() {
return this.myArray.getSize();
}
// 查看 隊列當前的容量
getCapacity() {
return this.myArray.getCapacity();
}
// 查看隊列是否爲空
isEmpty() {
return this.myArray.isEmpty();
}
// 輸出隊列中的信息
// @Override toString 2018-10-20-jwl
toString() {
let arrInfo = `Queue: size = ${this.getSize()},capacity = ${this.getCapacity()},\n`;
arrInfo += `data = front [`;
for (var i = 0; i < this.myArray.size - 1; i++) {
arrInfo += `${this.myArray.data[i]}, `;
}
if (!this.isEmpty()) {
arrInfo += `${this.myArray.data[this.myArray.size - 1]}`;
}
arrInfo += `] tail`;
// 在頁面上展現
document.body.innerHTML += `${arrInfo}<br /><br /> `;
return arrInfo;
}
}
複製代碼
Main
class Main {
constructor() {
this.alterLine('MyQueue Area');
let mq = new MyQueue(10);
for (let i = 1; i <= 10; i++) {
mq.enqueue(i);
console.log(mq.toString());
}
console.log(mq.getFront());
this.show(mq.getFront());
while (!mq.isEmpty()) {
console.log(mq.toString());
mq.dequeue();
}
}
// 將內容顯示在頁面上
show(content) {
document.body.innerHTML += `${content}<br /><br />`;
}
// 展現分割線
alterLine(title) {
let line = `--------------------${title}----------------------`;
console.log(line);
document.body.innerHTML += `${line}<br /><br />`;
}
}
複製代碼
MyQueue
void enqueue(E)
: O(1)
均攤E dequeue()
:O(n)
出隊的性能消耗太大了E getFront()
:O(1)
int getSize()
:O(1)
boolean isEmpty()
:O(1)
O(1)
,O(1)
。O(n)
,O(1)
。O(1)
了,front == tail
時隊列就爲空,tail+1==front
,(tail+1)%c==front
時就能夠擴容了,tail+1==front
變成(tail+1)%c==front
是由於(tail+1)%c==front
,因此隊列滿了,O(1)
了。(tail + 1) % data.length == front
(class: MyLoopQueue, class: Main)
MyLoopQueue
class MyLoopQueue {
constructor(capacity = 10) {
// 初始化新數組
this.data = new Array(capacity);
// 初始化 隊首、隊尾的值 (索引)
this.front = this.tail = 0;
// 隊列中實際元素個數
this.size = 0;
}
// 擴容
resize(capacity) {
let newArray = new Array(capacity);
let index = 0;
for (let i = 0; i < this.size; i++) {
// 索引可能會越界,因而就要取餘一下,
// 若是越界了,就從隊首開始
index = (this.front + i) % this.getCapacity();
newArray[i] = this.data[index];
}
this.data = newArray;
this.front = 0;
this.tail = this.size;
}
// 入隊
enqueue(element) {
// 判斷隊列中是否已滿
if ((this.tail + 1) % this.getCapacity() === this.front) {
this.resize(Math.floor(this.getCapacity() * 2));
}
this.data[this.tail] = element;
this.tail = (this.tail + 1) % this.getCapacity();
this.size++;
}
// 出隊
dequeue() {
// 判斷隊列是否爲空
if (this.isEmpty()) {
throw new Error("can't dequeue from an empty queue.");
}
let element = this.data[this.front];
this.data[this.front] = null;
this.front = (this.front + 1) % this.getCapacity();
this.size--;
// 當size 爲容量的四分之一時就縮容一倍
if (this.size === Math.floor(this.getCapacity() / 4)) {
this.resize(this.getCapacity() / 2);
}
return element;
}
// 查看隊首的元素
getFront() {
if (this.isEmpty()) {
throw new Error('queue is empty.');
}
return this.data[front];
}
// 查看實際的元素個數
getSize() {
return this.size;
}
// 查看容量
getCapacity() {
return this.data.length;
}
// 隊列是否爲空
isEmpty() {
// return this.size === 0;
return this.front == this.tail;
}
// 輸出循環隊列中的信息
// @Override toString 2018-10-20-jwl
toString() {
let arrInfo = `LoopQueue: size = ${this.getSize()},capacity = ${this.getCapacity()},\n`;
arrInfo += `data = front [`;
for (var i = 0; i < this.myArray.size - 1; i++) {
arrInfo += `${this.myArray.data[i]}, `;
}
if (!this.isEmpty()) {
arrInfo += `${this.myArray.data[this.myArray.size - 1]}`;
}
arrInfo += `] tail`;
// 在頁面上展現
document.body.innerHTML += `${arrInfo}<br /><br /> `;
return arrInfo;
}
}
複製代碼
Main
class Main {
constructor() {
this.alterLine('MyLoopQueue Area');
let mlq = new MyQueue(10);
for (let i = 1; i <= 10; i++) {
mlq.enqueue(i);
console.log(mlq.toString());
}
console.log(mlq.getFront());
this.show(mlq.getFront());
while (!mlq.isEmpty()) {
console.log(mlq.toString());
mlq.dequeue();
}
}
// 將內容顯示在頁面上
show(content) {
document.body.innerHTML += `${content}<br /><br />`;
}
// 展現分割線
alterLine(title) {
let line = `--------------------${title}----------------------`;
console.log(line);
document.body.innerHTML += `${line}<br /><br />`;
}
}
複製代碼
O(n)
,
O(1)
,MyQueue
:數組隊列,使用了自定義數組
void enqueue(E)
:O(1)
均攤E dequeue()
:O(n)
出隊的性能消耗太大了E getFront()
:O(1)
int getSize()
:O(1)
boolean isEmpty()
:O(1)
MyLoopQueue
:循環隊列,沒有使用自定義數組
void enqueue(E)
:O(1)
均攤E dequeue()
:O(1)
均攤E getFront()
:O(1)
int getSize()
:O(1)
boolean isEmpty()
:O(1)
O(n)
的複雜度變爲了O(1)
的複雜度,O(1)
爲均攤的時間複雜度,O(1)
的時間複雜度。O(n)
的複雜度要比O(1)
要慢,
MyQueue,time:15.463472711s
,MyLoopQueue,time:0.009602136s
,MyLoopQueue,time:2.663835877s
,O(1)
對O(n)
、O(n)
對O(n^2)
、O(n)
對O(logn)
。PerformanceTest
class PerformanceTest {
constructor() {}
testQueue(queue, openCount) {
let startTime = Date.now();
let random = Math.random;
for (var i = 0; i < openCount; i++) {
queue.enqueue(random() * openCount);
}
while (!queue.isEmpty()) {
queue.dequeue();
}
let endTime = Date.now();
return this.calcTime(endTime - startTime);
}
// 計算運行的時間,轉換爲 天-小時-分鐘-秒-毫秒
calcTime(result) {
//獲取距離的天數
var day = Math.floor(result / (24 * 60 * 60 * 1000));
//獲取距離的小時數
var hours = Math.floor((result / (60 * 60 * 1000)) % 24);
//獲取距離的分鐘數
var minutes = Math.floor((result / (60 * 1000)) % 60);
//獲取距離的秒數
var seconds = Math.floor((result / 1000) % 60);
//獲取距離的毫秒數
var milliSeconds = Math.floor(result % 1000);
// 計算時間
day = day < 10 ? '0' + day : day;
hours = hours < 10 ? '0' + hours : hours;
minutes = minutes < 10 ? '0' + minutes : minutes;
seconds = seconds < 10 ? '0' + seconds : seconds;
milliSeconds =
milliSeconds < 100
? milliSeconds < 10
? '00' + milliSeconds
: '0' + milliSeconds
: milliSeconds;
// 輸出耗時字符串
result =
day +
'天' +
hours +
'小時' +
minutes +
'分' +
seconds +
'秒' +
milliSeconds +
'毫秒' +
' <<<<============>>>> 總毫秒數:' +
result;
return result;
}
}
複製代碼
Main
class Main {
constructor() {
this.alterLine('Queues Comparison Area');
let mq = new MyQueue();
let mlq = new MyLoopQueue();
let performanceTest = new PerformanceTest();
let mqInfo = performanceTest.testQueue(mq, 10000);
let mlqInfo = performanceTest.testQueue(mlq, 10000);
this.alterLine('MyQueue Area');
console.log(mqInfo);
this.show(mqInfo);
this.alterLine('MyLoopQueue Area');
console.log(mlqInfo);
this.show(mlqInfo);
}
// 將內容顯示在頁面上
show(content) {
document.body.innerHTML += `${content}<br /><br />`;
}
// 展現分割線
alterLine(title) {
let line = `--------------------${title}----------------------`;
console.log(line);
document.body.innerHTML += `${line}<br /><br />`;
}
}
複製代碼