數據結構的那些事(一)

前端早已不是當年的切圖仔了。想要升職加薪,進軍大廠,在前端的路上走的更遠,你不得不瞭解一下數據結構。前端

經常使用的數據結構有:數組,列表,棧,隊列,鏈表,字典,散列表,樹,圖。

咱們會在接下來一個一個的介紹,而且實現它們!數組

1.數組:最多見也是用的最多的數據結構就是數組了。它經過索引來實現元素的任意存儲。

大多數語言都有數組,值得一提的是,JavaScript中的數組是一種特殊的對象,所以索引在內部會被轉換成字符串類型,因此效率會有所折扣。bash

由於數組你們瞭解的比較多,在這裏只提下數組的迭代器方法:

不生成新數組的迭代器方法:數據結構

forEach():接收一個函數做爲參數,對數組中每一個元素使用該函數
every():接收一個返回值爲布爾值的函數,遍歷數組,對於全部函數返回true,該方法返回true
some():接收一個返回值爲布爾值的函數,遍歷數組,只要有一個函數返回true,該方法返回true
reduce():使用接收的函數操做數組,最後返回一個結果
複製代碼

生成新數組的迭代器方法app

map()
filter()
複製代碼

2.列表:適用於保存元素很少,不須要在一個很長的序列中查找元素,或對其排序。

列表是一組有序的數據,每一個列表中的數據項稱爲元素。 首先咱們來設計一下這個列表應該具備哪些屬性和方法:函數

function List() {
    this.listSize = 0;
    this.pos = 0;
    this.dataStore = []; // 初始化一個空數組來保存列表元素
    this.clear = clear;
    this.find = find;
    this.toString = toString;
    this.insert = insert;
    this.append = append;
    this.remove = remove;
    this.front = front;
    this.end = end;
    this.prev = prev;
    this.next = next;
    this.length = length;
    this.currPos = currPos;
    this.moveTo = moveTo;
    this.getElement = getElement;
    this.length = length;
    this.contains = contains;
}
複製代碼

當咱們設計好一個列表類後,接下來開始實現裏面的方法:ui

//append
function append(e){
    this.dataStore[this.listSize++] = e;
}
//remove方法要求咱們首先要找到刪除的元素,咱們須要一個輔助方法find()
function find(e){
    for(let i = 0; i<this.dataStore.length; ++i){
        if(this.dataStore[i] === e){
            return i
        }
    }
    return -1
}
function remove(e){
    let findCode = this.find(e);
    if(indCode > -1){
        this.dataStore.splice(findCode, 1);
        --this.listSize;
        return true;
    }
    return false;
}
//insert 向列表中插入一個元素
function insert(e, where){
    let insetPos = this.find(where);
    if(insertPos > -1){
        this.datastore.splice(insertPos+1, 0 , e);
        ++this.listSize;
        return true;
    }
    return false;
}
//length
function length(){
    return this.listSize;
}
//清空列表中的元素
function clear(){
    delete this.dataStore;
    this.dataStore = [];
    this.listSize = this.pos = 0;
}
//cotains判斷給定值是否在列表中
function coatains(e){
    for(let i = 0; i<this.dataStore.length; ++i ){
        if(this.dataStore[i] === e){
            return true;
        }
    }
    return false;
}
複製代碼

最後,咱們還須要一組方法來遍歷列表this

function front() {
    this.pos = 0;
}
function end() {
    this.pos = this.listSize-1;
}
function prev() {
    if (this.pos > 0) {
        --this.pos;
    }
}
function next() {
    if (this.pos < this.listSize-1) {
        ++this.pos;
    }
}
function currPos() {
    return this.pos;
}
function moveTo(position) {
    this.pos = position;
}
function getElement() {
    return this.dataStore[this.pos];
}
複製代碼

到這裏,咱們就本身實現了一個列表類。有本身的屬性,能夠增刪改查,能夠遍歷。spa

3.棧:棧是和列表相似的一種數據結構,可是它遵循後進先出的規則

由於數據只能在棧頂添加或刪除,因此這樣的操做很快,並且容易實現。 對棧的兩種主要操做是將一個元素壓入棧和講一個元素彈出棧,另外一個經常使用操做是訪問棧頂元素。 同樣的,在實現以前,咱們先來設計一下棧應該具備的屬性和方法:設計

function Stack() {
    this.dataStore = [];//存儲
    this.top = 0;//棧頂
    this.push = push;//入棧操做
    this.pop = pop;//出棧操做
    this.peek = peek;//獲取棧頂元素
}
複製代碼

接下來咱們來實現這些方法:

function push(e){
    this.dataStore[this.top++] = e;
}

function pop(){
    return this.dataStore(--this.top);
}

function peek(){
    return this.dataStore[this.top - 1];
}
複製代碼

有時候須要知道棧內存儲元素個數,能夠定義一個length方法:

function length(){
    return this.top
}
複製代碼

清空棧也很簡單:

function clear(){
    this.top = 0;
}
複製代碼
適合使用棧的場景:

(1)數制間的相互轉換

eg:將數字轉換爲二進制和八進制
function changeBase(num, base){
    let s = new Stack();
    do{
        s.push(num % base);
        num = Math.floor(num /= base);
    }while(num > 0)
    let convert = "";
    while(s.length() > 0){
        convert += s.pop();
    }
    return convert;
}

複製代碼

(2)迴文:迴文指從前日後寫和從後往前寫都是同樣的結構。使用棧能夠輕鬆地判斷一個字符串是不是迴文。

字符串完整壓入棧內後,經過持續彈出棧中的每一個字母就能夠獲得一個新的字符串,該字符串恰好與原來的字符串順序相反。咱們只須要比較這連個字符串是否同樣便可判斷是否是迴文。

(3)用棧來模擬遞歸

function fact(n){
    let s = new Stack();
    while(n > 1){
        s.push(n--);
    }
    let product = 1;
    while(s.length() > 0){
        product *= s.pop();
    }
    return product;
}
複製代碼

避免一篇博客過長,我會將數據結構分紅幾篇來寫,喜歡的幫忙點個贊,給博主一點動力~~

相關文章
相關標籤/搜索