我一直沒搞懂數據結構到底是個啥?直到看到這篇文章!

抱歉,我真的學不會

又要說起我的血淚史了😂

我當初上大學學習數據結構是學的這本教材:

在這裏插入圖片描述
應該有不少夥伴都是學的這本吧(完了,上篇文章一發,大家都知道我數據結構60分了,沒法混了🤣),最近啊,有許多小夥伴知道我要連載數據結構與算法系列,就跑過來私信給我“慶哥啊,這數據結構真的搞得我頭大,這都是啥啊😂”

不怕你笑話,我大學四年都沒有搞懂數據結構這玩意到底是個啥?😂(我真的有那麼笨嗎?尷了個大尬)

上大學那會,總覺得這玩意太抽象,學不明白,越往後學越跟不上,還沒到一半就掉隊了,基本上屬於放棄治療的那種,後來知道啊,這書上寫的都是僞代碼,我說怎麼把我看得一愣一愣的,就這樣,整個四年大學,我愣是沒有搞懂數據結構是個啥?

然後嘞,那些搞懂的,順利參加校招,拿到滿意offer,進入大廠,迎娶白富美……而我呢?

面試官:“數據結構有了解嗎?”

我:“啥?你說啥?數據結構是個啥?”

然後我就順利畢業了……

**扎心不,老鐵?**你是不是也是這樣啊,正在讀大學,數據結構也是一臉懵逼,或者畢業了,還是不知道數據結構到底是個啥,說出去怪尷尬,沒事,看了今天這篇文章,保準你可以出去大聲喊“我……終於……知道……數據結構是個啥啦”(拉長音……)

數據結構你到底啥玩意啊?

第一次接觸“數據結構”的時候,覺得有點抽象,不過覺得也沒有那麼難理解,嗯嗯,應該是這樣的,誰知道,越學越迷糊,咱們先看看,這個數據結構怎麼定義的:

數據結構是相互之間存在一種或多種特定關係的數據元素的集合,換句話說,數據結構是帶“結構”的數據元素的集合,“結構”就是指數據元素之間存在的關係。

不知道大家看到這段定義什麼感覺,反正我當時看着有點迷糊,不過我現在再來看,覺得說的挺好的。

聊聊數據在計算機中的存儲

要想比較好的理解數據結構,你得先了解數據在計算機中的存儲,我們舉個簡單的例子,比如我們要存儲一個數字,比如1024吧,怎麼存儲嘞,我們知道,一般這樣寫代碼(java)):

int a = 1024;

也就是定義一個整型,我們寫完它,是保存在我們的電腦上,實際上是保存在了我們電腦中的硬盤中,程序要加載進內存纔可以被CPU讀取運行,所以啊,這個1024實際上得裝載進內存中,這裏需要說明的是,這個1024是我們寫的一個程序中的一個整型變量,你還得明白的是,我們這裏說它保存在內存中,是因爲要運行這段程序了。

一旦運行這段程序,這個程序中包含的數據就要裝載進內存中,就好比這裏的1024,也要保存進內存,那麼它怎麼保存嘞?這裏你還要記住這麼一句話:

計算機中的數據都是以二進制的形式保存的

因此嘞,這個1024是十進制,要轉換成二進制保存在內存中,內存有一定的大小,你要保存一個整數,你是不是得佔用內存的一些空間啊,假如是這樣:

在這裏插入圖片描述
你看,這樣這個1024就被存在了內存中,當然,你得明白,這個1024其實被轉換成了二進制形式,我這樣只是爲了便於表示說明。

這塊不瞭解的可以看看我之前寫的這幾篇文章:

一個程序在計算機中是如何運行的?超級乾貨!!!

作爲一個程序員,CPU的這些硬核知識你必須會!

作爲一個程序員,內存的這些硬核知識你必須懂!

作爲一個程序員,內存和磁盤的這些事情,你不得不知道啊!!!

再來說數據結構

瞭解了數據在計算機中大致怎麼存儲以後,我們就可以再來看數據結構這傢伙了,定義我們之前看過了,怎麼去理解嘞,數據結構從名字上看,就是數據和結構,結構可以理解爲關係,就是數據之間存在什麼樣的關係……

這樣說,你其實還是有點迷糊,你可以這樣理解,首先嘞,你先清楚,數據結構啊,它是一門學科,幹啥的嘞?說白了,就是研究數據該怎麼存儲?

你可能說了,還研究怎麼存儲,難道存儲不都是一樣的嗎😂,雖然這個問題有點chun,但是嘞,確實是個讓小白疑惑的問題,數據的存儲當然是不一樣的啊,舉個例子吧,假如我們要存儲一個五個整數{1,2,3,4,5},你內存中咋麼個存儲,可能是這樣:

在這裏插入圖片描述
啥意義嘞?就是這五個數字啊,在內存中是排成一排的,一個挨着一個,但是有可能也是這樣的:

在這裏插入圖片描述
就是在內存中沒啥順序,零散的存放,所以啊你看,對於數據,可以按照不同的方式去存儲,是給你連續挨着存放,還是存放在哪就存放在哪啊,你可能要問啦,哪這咋整,這個嘛,就得看數據本身以及其他相關要求,看看你這個數據以後準備怎麼用,然後考慮怎麼存放比較合適。

所以啊,數據結構啊,就是來管理數據在內存中的存儲的,比如,有一些數據要在內存總存儲,那就得看數據結構,數據結構讓你怎麼存放你就得怎麼存放,讓你連續存放,你就不能撒花似的哪都是的。

另外啊,你還需要知道,這裏的數據結構是個統稱,就好比水果,它有香蕉蘋果和橘子,數據結構也是一樣啊,它是個總稱,有數組,鏈表,棧和隊列等等,這些都屬於數據結構,就好比,香蕉蘋果和橘子都是水果,這個好理解吧!

然後嘞,這些數據結構啊,每個都有它們自己的一些特點,這些特點就是規定如果數據選擇了它這種數據結構來存儲,就要按照它的要求在內存中存放,比如你選擇了數組,那麼你這些數據就要在內存中連續存儲,一個挨着一個,不能亂,而如果你選擇了鏈表這種存儲結構,那在內存中就不要求你非得連續存儲,隨意,有空地你就可以存儲。

所以你看,不同的數據結構有它特定的用途……

到了這裏,你差不多就理解了數據結構是個啥了吧,也就是說啊,數據結構就是研究數據怎麼存儲嘞,然後數據結構是個總稱,好比水果,其下有數組,鏈表,棧和隊列這些數據結構,好比水果有香蕉蘋果和橘子,其實嘞,你就可以把數據結構想象成一個容器,容器是幹啥的嘞,盛東西的啊,這裏就是存儲數據的,而這些容器形狀各異,你選擇了不同的容器(數據結構),那麼就意味着數據的存儲形式是不同的。

說了那麼多,到此爲止了嘛?當然不,而且差的還遠着嘞😂,我們上面說的存儲的五個數據,可以想象的到,這五個數據之間並沒有啥聯繫,頂多就是連續存儲的時候,一個挨着一個,這樣存在一對一關係,也就是跟站隊似的,你前面有我,我後面有你。

但是還有一種數據,比如我們要存儲一個家譜中的數據信息,比如這樣:

在這裏插入圖片描述
你想一下,如果是這樣的話,怎麼存儲到內存中嘞?這些不同於那些冷冰冰的數字,保存進內存就萬事大吉了,這種家譜數據我們保存的時候其實保存的不僅僅是數據,最重要的是還要保存各個數據之間的關係。

經過上面的介紹,想必你肯定知道個小大概了,那就選擇一種數據結構來存儲它唄,說的不錯,我們分析家譜數據可以發現,這些數據擁有一對多的關係,比如爺爺有三個兒子,大伯有兩個小孩,像這種數據,數據結構中有一種結構叫做樹的是可以保存這樣的數據的。

我們上面說的這些一對一,一對多都是表示數據之間的關係,其實也就是數據結構中的結構,這裏可能有人問了,那有沒有多對多的關係呢?答案肯定是有的,那麼這種該怎麼存儲嘞?沒事,數據結構中還有個叫圖的,就是專門針對多對多的數據的。

所以你看,數據結構是個啥,不就是管着數據該怎麼存儲嘛?

數據結構都有哪些嘞?

那麼,你肯定好奇,那麼,數據結構都有哪些啊?數據結構總的來說有如下三大類:

  • 線性表,也就是數組、鏈表、棧和隊列;
  • 樹結構,包括普通樹,二叉樹,紅黑樹等等;
  • 圖存儲結構,這玩意有點難😂;

接下來我對這些數據結構做一下簡單的介紹。

線性表

線性表其實也是個統稱,它包含順序表和鏈表,還有棧和隊列這些,線性表其實好理解,線性一詞就很明白了,說明數據都是一對一的關係,存儲的形式也都是依次排列。

這裏說到依次排列,可能有人會在數組和鏈表這裏犯迷糊,數組很明確,需要連續的內存空間,數據連續存放,一個挨着一個,說這是依次排列,那ok,可是鏈表嘞,不是說鏈表不要求非得連續排列嘛?是的,確實如此,但是鏈表實際的存儲爲了保持這種依次排列,它引入了指針,就比如這樣:

在這裏插入圖片描述
數組是這樣的:

在這裏插入圖片描述

所以啊,鏈表也是線性表,也是依次排列的,這個要理解,另外這裏你可能也會聽到順序表這個概念,初學者的話,你就可以把順序表等價爲數組,聽我的沒錯。

然後就是棧和隊列了,這倆也是線性表,只不過是比較特殊的線性表,它們對數據的進出做了明確的要求,這裏我就不多說了,我之前寫文詳細了介紹了這些線性表,你們可以看看:

來吧!給你不一樣的數組深入講解!

鏈表不會?看這個立馬就懂!

輕輕鬆鬆學會棧和隊列(附有順序棧的實現思路分析)

來吧!一文徹底搞定哈希表!

來吧!一文徹底搞定數據結構之樹!

看了這篇對二叉樹的介紹,除了不會寫代碼啥都會!!!

Java代碼實戰:通過手寫一個單鏈表,告訴你學習編程的方法和捷徑!

樹結構

其實我覺得,越往下,是越難的,像樹結構就比線性表難一點,不過也是,線性表是一對一的數據關係,而樹結構就是一對多了,肯定會複雜一點。

說到樹啊,什麼二叉樹,紅黑樹,B+樹等等,這些都是重點知識,而且學起來我覺得都有點難度,說實話,數據結構與算法真的有難度,不過別擔心,跟着慶哥我,別掉隊,今年咱們一起拿下它。

那麼樹結構啊,我們上面也說了,就是存儲那些具有一對多關係的數據,典型的有家譜啊,公司組織架構啥的,反正數據之間具有一對多,滿足這種關係就可以使用樹結構來存儲。

圖結構

自然而然,圖結構就是存儲那些具有多對多關係的數據,這自然比前兩者都要複雜的多,學起來也是有挑戰的啊,它大概是這麼一個關係:

在這裏插入圖片描述

數據的邏輯結構與物理結構

經過我們上面的介紹,相信你已經get到不少乾貨了,那麼接下來還要繼續爲你不一些硬貨,那就是關於數據的邏輯結構和物理結構。

到這裏我們已經知道了什麼是數據結構,以及都是有哪些數據結構,我們上面也做了簡單的分析,說了說各個數據結構,那麼你有沒有想過,我們該如何選擇這些數據結構去存儲數據呢?上面也提到過,那就是要看數據本身了。

實際上,對於數據的存儲該選擇什麼樣的數據結構,那就要取決於數據的邏輯結構和物理結構,再次聲明下,這點的理解很重要,以下我說的每個字都不要漏掉哦😁

啥是邏輯結構?

不知道你們之前有沒有想過這個問題,數據的邏輯結構是個啥?可能你有點迷糊,但是說起來真的很簡單:

數據的邏輯結構就是指的數據之間存在的關係

我想經過上面的講解,你這裏立馬就知道,這裏指的關係就是上面說的什麼一對一,一對多和多對多了,不錯,就是這些,這裏的數據的邏輯結構指的就是這麼些個關係,就好比我上面給的那個圖,我們再來看一下:

在這裏插入圖片描述
比如上圖中的大伯,二伯和爸爸,他們都屬於兄弟關係,爺爺有三個兒子,大伯有兩個孩子,這就是一對多的關係,像這種數據,我們要存儲的話,不僅要存儲基本數據信息,更重要的也要存儲着他們之間存在的關係。

而這種關係就是數據之間的邏輯結構。

這裏總結一下,數據之間的邏輯結構大致分爲三種,也就是:

  1. 一對一:就是那種你挨着我,我挨着你的數據,比如數組
  2. 一對多:就是我們上面畫的家譜圖那樣
  3. 多對多:這個比如說地圖,或者一些四通八達的路,能明白我的意思吧😂

其實吧,給到你一些數據,你基本上都能判斷出這些數據是什麼關係,也就是說,數據的邏輯結構不難辨認。

到了這裏,你有沒有發現,這三種邏輯結構的數據,正好可以用我們上面介紹的三大類的數據結構去存儲,想一下,也就是下面三種:

  1. 線性表:一對一
  2. 樹結構:一對多
  3. 圖結構:多對多

有沒有發現,萬變不離其中啊,只是我們瞭解了邏輯結構這個知識點後,你會覺得這塊的只是更加的完整。

物理結構又是個啥?

重要知識點

我們在上面知道了啥是邏輯結構,那麼我們就可以分析數據之間的邏輯結構來看看數據該選用哪一種數據結構來存儲,這看似已經萬事大吉,沒啥事了,但是,實則不然,其實吧,說到這裏,牽涉到的知識點又不少,我這裏只給你說重點,詳細的以後單獨拿出來嘮叨嘮叨。

你先記住這非常重要的一句話:

數據結構的存儲方式只有兩種:數組(順序存儲)和鏈表(鏈式存儲)。

啥意思嘞?其實吧,數組和鏈表是數據結構中的數據結構,其他的數據結構都可以用數組和鏈表來實現,你比如拿棧來說吧,可以用數組來實現棧,這就叫做順序棧,也可以用鏈表來實現棧這個就叫做鏈式棧。

所以啊,每種數據結構的存儲其實都可以分爲順序存儲(用數組實現)和鏈式存儲(用鏈表實現)

你比如說要使用隊列這個數據結構來存儲數據,那實際上,就可以分爲順序隊列實現和鏈式隊列實現,也就是看你實際內存中怎樣去存儲這些數據,因此,你可以看出,數組和鏈表是數據結構中的基石啊!

那麼,新的問題就來了,既然對於每個數據結構都可以有順序存儲和鏈式存儲,那麼即時我依據數據的邏輯結構選擇了一個數據結構,那麼我怎麼來確定是要順序存儲還是要鏈式存儲呢?

PS:上面的這個問題很重要,你一定要理解,不理解的把上面幾段話多讀幾遍,一定要理解,一定要理解!

這個問題的關鍵所在就是要分析數據的物理結構了?

再看物理結構

那啥是數據的物理結構呢?同樣的,如果你之前沒有想過這個問題,同樣會覺得迷糊,但是其實也是很簡單的:

數據的物理結構就是指的數據在內存中的存儲是連續存儲,也就是集中在一塊的意思,還是零散的分散存儲。

也就是說啊,對於一些數據,我們分析得出他們之間的邏輯結構,知道了數據之間具有什麼樣的關係,這個我們可以確定數據結構了,但是我們還要分析數據的物理結構,可是,你有沒有發現問題,我們怎麼知道數據的物理結構是啥呢?

這裏要看兩點,來讓我們決定數據的物理結構,分別是:

  1. 內存的空間狀態
  2. 數據的用途

啥意思嘞?我們拿內存空間的狀態來說,首先啊,我們得知道,連續存儲要求有連續的內存空間,比如我們要存儲10M大小的數據,那就是要求內存中也要有一整塊空間是10M,但是如果沒有的話那肯定是用不了連續存儲了,那隻能分散存儲,否則存儲不成功啊。

再來看數據的用途,對於連續存儲和分散存儲主要的一個區別就是會影響到後續數據的操作,就拿連續存儲來說,它對數據的遍歷效率比較高,因此,如果你存儲的這些數據後續的操作中遍歷比較頻繁,那肯定優先選擇連續存儲,當然,如果你後續的數據操作中會進行比較多的更新操作的話,那就優先選擇分散存儲了,因爲它效率更高。

所以我們根據內存的空間狀態數據的用途來確定數據的物理結構是連續存儲還是分散存儲,然後再選擇對應的存儲方式,也就是:

  1. 物理結構爲連續存儲就選擇順序存儲
  2. 物理結構爲分散存儲就選擇鏈式存儲

可能會有那麼一點繞,多理解理解!

感謝閱讀

大學的時候選擇了自學Java,工作了發現吃了計算機基礎不好的虧,學歷不行這是沒辦法的事,只能後天彌補,於是在編碼之外開啓了自己的逆襲之路,不斷的學習Java核心知識,深入的研習計算機基礎知識,所有心得全部書寫成文,整理成有目錄的PDF,持續原創,PDF在公衆號持續更新,如果你也不甘平庸,那就與我一起在編碼之外,不斷成長吧!

其實這裏不僅有技術,更有那些技術之外的東西,比如,如何做一個精緻的程序員,而不是“屌絲”,程序員本身就是高貴的一種存在啊,難道不是嗎?

非常歡迎你的加入,未來的日子,編碼之外,有你有我,一起做一個人不傻,錢很多,活得久的快樂的程序員吧!

回覆關鍵字“PDF”,獲取技術文章合集,已整理好,帶有目錄,歡迎一起交流技術!

另外回覆“慶哥”,看慶哥給你準備的驚喜大禮包,只給首次關注的你哦!

任何問題,可以加慶哥微信:H653836923,另外,我有個交流羣,我會***不定期在羣裏分享學習資源,不定時福利***,感興趣的可以說下我邀請你!

對了,如果你是個Java小白的話,也可以加我微信,我相信你在學習的過程中一定遇到不少問題,或許我可以幫助你,畢竟我也是過來人了!

在這裏插入圖片描述

感謝各位大大的閱讀🥰

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