講個大部分數據結構和算法教科書中都不會講的問題

講個大部分數據結構和算法教科書中都不會講的問題

大部分數據結構和算法書籍中,在講某種數據結構和算法的時候,都會拿整數、字符串這些基本數據類型,作爲要處理的數據的類型。實際上,在真實的軟件開發中,數據結構中存儲的數據、算法要處理的數據,往往都不是簡單的整數,而是”對象“。這裏的”對象“很好理解,就是編程語言的中的”類與對象“中的對象。比如下面這幾行Java代碼,我們用紅黑樹來存儲Order訂單對象。

// 紅黑樹來存儲訂單,key是訂單ID,value是訂單對象
private TreeMap<long, Order> id2OrderMap = new TreeMap<>();
public void add(Order order) {
    // 添加一個訂單
    id2OrderMap.put(order.id, order);
}
private class Order {
    // 訂單類
    public long id;
    public long userId;
    public long createTime;
    // ...more fields...
}

不過,你可能會有疑問,既然在真實的軟件開發中,數據結構和算法要處理的都是對象,那爲啥書本中都可以按照拿整數(或字符串)類型,而不是對象來講解呢?

我們知道,數據結構和算法要解決的都是”更快“、”更省“的問題。更快指代碼的執行速度,更省指存儲空間的消耗。

”更快“這裏你先簡單理解爲”查找更快“,當然還有增刪改以及一些統計操作,不過,都差不多,你理解了”查找“,其他的操作也就都理解了。我們在一組數據中,查找一個想要的數據的時候,都是通過某個鍵值(key)來查找的。

這裏的鍵值怎麼理解呢?我們拿剛剛的訂單的例子來說明一下。我們希望在這組訂單中,按照訂單ID來快速的查找訂單。那我們就把訂單的ID看做鍵值(key),並且按照key來組織成紅黑樹這種數據結構。紅黑樹中存儲的是key值和訂單對象的內存地址,而訂單對象本身是存儲在另外的內存空間中的(像Java這種語言,就是存儲在堆內存中的)。

爲了方便你理解,我畫了一張圖,你可以對比着文字描述看下。

講個大部分數據結構和算法教科書中都不會講的問題

那你可能說,那我要是再想通過訂單的用戶ID來查找訂單呢?這個時候該怎麼辦呢?

你就可以再以用戶ID作爲鍵值,創建另外一個紅黑樹。實際上,這就是我們之前文章中提到的多重索引結構。如果翻譯成Java代碼的話,就是下面這一個樣子。

// 兩個索引
private TreeMap<long, Order> id2OrderMap = new TreeMap<>();
private TreeMap<long, Order> userId2OrderMap = new TreeMap<>();
public void add(Order order) {
    // order在外部創建,內存中只有一份
    id2OrderMap.put(order.id, order);
    userId2OrderMap.put(order.userId, order);
}
private class Order {
    public long id;
    public long userId;
    public long createTime;
    // ...more fields.
}

如果畫成圖的話,就是下面這個樣子。你會發現,訂單對象是隻有一份的,而索引結構有兩份,一份是按照訂單的ID作爲鍵值創建的,另一份是按照訂單的用戶ID作爲鍵值創建的。

講個大部分數據結構和算法教科書中都不會講的問題

你可能會說,兩份索引是不是比較浪費內存空間啊?實際上,並不會。

從我前面的講解中,你應該已經知道,索引中存儲的只是就鍵值和對象的內存地址,如果鍵值是大小比較小的整數,而對象是比較大的對象(數據本身),那索引所佔用內存空間比起對象所佔用的內存空間來說,要小很多。

還是剛纔那個訂單的例子,如果一個訂單對象中包含很多字段,大小是1KB,而紅黑樹索引中,每個節點(對應一個訂單對象)的大小要遠小於1KB(這個你可以自己算下)。所以,所佔用內存空間會遠小於訂單數據本身存儲所需的內存空間。

也就是說,在實際上的軟件開發中,如果你要存儲、要處理的是大對象,那索引所佔的內存空間,是可以忽略的。當然,這個要權衡實際上情況來看,不可生搬硬套。

回到開頭的問題,既然真實的軟件開發中,數據結構和算法處理的數據類型都是對象,那爲什麼大部分數據結構和算法教科書中,都是拿整數類型來講解呢?

因爲我們在構建數據結構的時候,是按照鍵值構建,算法在執行的時候,也是按照鍵值來處理數據。鍵值一般都是整數或者字符串這些基本類型,我們拿基本類型來講解,簡單明瞭,足夠了。

讀者福利:

分享免費學習資料

針對於還會準備免費的Java架構學習資料(裏面有高可用、高併發、高性能及分佈式、Jvm性能調優、MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)
爲什麼某些人會一直比你優秀,是因爲他本身就很優秀還一直在持續努力變得更優秀,而你是不是還在滿足於現狀內心在竊喜!希望讀到這的您能點個小贊和關注下我,以後還會更新技術乾貨,謝謝您的支持!

資料領取方式:加入粉絲羣963944895,私信管理員即可免費領取

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章