本文的原始碼在我的github,可以參考一下
陣列是資料結構中最簡單,也是使用最廣泛的一種。在原生的js中,陣列給我們提供了很多方便的操作方法,比如push()
, pop()
, shift()
, unshift()
。但是出於對資料結構的學習,我們將不使用這些已有的方法,而是自己實現這些方法。這樣也方便我們計算其時間複雜度。這裡我們選擇使用TypeScript
實現,主要是因為TypeScript的強型別控制,以及泛型這些高階特性。
先來看我們自己實現陣列的例項屬性以及建構函式,我們用capacity來表示陣列的容量,雖然在TypeScript中並沒有像Java那樣嚴格限定陣列長度,但我們仍然希望儘量接近Java。我們用size來表示當前陣列中元素的個數
class MyArray<T> {
private data: Array<T>;
private size: number = 0;
constructor(capacity = 10) {
this.data = new Array(capacity);
}
}
1.在陣列中插入元素
在陣列index位置插入元素是我們經常使用的一個操作,那我們就需要從之前陣列中index位置開始,每個元素向後移動一個位置。以便給新插入的元素挪出位置。在操作的末尾,我們需要維護一下陣列的size.
public add(index: number, e: T) {
if (index < 0 || index > this.size) {
throw new Error('Add failed. Required index >= 0 and index <= size.');
}
if (this.size === this.data.length) {
this.resize(2 * this.data.length);
}
for (let i = this.size - 1; i >= index; i--) {
this.data[i + 1] = this.data[i];
}
this.data[index] = e;
this.size++;
}
在陣列中新增元素,最好情況下,使用者只用操作一次,時間複雜度是O(1);最差的情況下,使用者需要操作size次,時間複雜度是O(n)
這裡有一點需要注意,當陣列當前元素的個數size和capacity相等時,我們需要給陣列進行擴容為2倍處理,這個我後面會專門提及
2.在陣列中查詢元素和修改元素
這個沒啥好說的,查詢和修改陣列中某個元素複雜度就是O(1)
public get(index: number): T {
if (index < 0 || index >= this.size) {
throw new Error('Get failed. Index is illegal.');
}
return this.data[index];
}
3.在陣列中刪除元素
在陣列index位置刪除元素,這裡我們需要把陣列從index+1位置開始,每個元素向前移動一個元素
public remove(index: number): T {
if (index < 0 || index >= this.size) {
throw new Error('Remove failed. Index is illegal.');
}
let ret = this.data[index];
for (let i = index + 1; i < this.size; i++) {
this.data[i - 1] = this.data[i];
}
this.size--;
this.data[this.size] = undefined;
// 如果陣列中的元素僅為陣列容量的1/4時,這時需要進行縮容操作
if (this.size === this.data.length / 4 && this.data.length / 2 !== 0) {
this.resize(this.data.length / 2);
}
return ret;
}
在陣列中刪除元素,最好情況下,使用者只用操作一次,時間複雜度是O(1);最差的情況下,使用者需要操作size次,時間複雜度是O(n)
當陣列中的元素個數僅為陣列容量的1/4時,我們需要對陣列進行縮容為1/2操作
4.陣列的擴容或者縮容
陣列的擴容和縮容操作很簡單,原理就是接受一個新的容量,把之前陣列中的內容複製到新陣列中,並返回新的陣列
private resize(newCapacity: number): void {
let newData = new Array(newCapacity);
for (let i = 0; i < this.size; i++) {
newData[i] = this.data[i];
}
this.data = newData;
}
更多相關資料結構,可以前往我的github。持續更新中,喜歡的話給個star~