數據結構(2)線性表-順序表

知道一個算法的好壞怎么去判斷以后,就該正式的去學習一些常見的數據結構,當然,這里的數據結構僅僅是初階,不會挨個一個一個學完,后期慢慢來。

一、數據結構總論

一般按照邏輯結構和存儲結構來分類,在初階的學習時,雖不能全部學完,但基本每個類別都能見到例子。

1.按邏輯結構分類

按照邏輯結構分類,可以分為集合結構(數據元素同屬于一個集合,但是并沒有任何的關系)、線性結構(數據元素一對一,好像一條線一樣連在了一起)、樹形結構(數據元素一對多的關系,就好像一個樹的主干的根只有一個,但是他身上每一個節點都可能有好幾個樹枝)、圖狀/網狀結構(這種結構就類似于在天上俯瞰一個城市的公路一樣,每條路的十字看做一個數據元素的話,那就是多對多的關系)

2.按存儲結構分類

按照存儲結構有順序存儲(如數組,數組元素就是在內存中連續的存儲)、鏈式存儲(其實在C語言學習結構體的時候我們就已經見過怎樣建立一個鏈表節點,即一個數據域,一個地址,這個地址是指向鏈式存儲的下一個數據元素)、索引存儲、哈希存儲(根據散列函數的計算而定位數據元素)。

二、線性表

線性表是一類數據結構的總稱,這一類數據結構最明顯的特點就是邏輯上是線性的,但是物理上不一定是線性的。

也就是說,線性表在使用的時候,在我們的大腦中思考就是連續的、線性的,但實際上在內存中的存儲可不一定是順序存儲。

三、順序表

1.概述

這次學習的順序表就是屬于線性表,符合線性表的特征,即邏輯結構是線性結構,且數據順序存儲(底層實現類似于數組,或者說借助于數組)。

2.順序表和數組的區別

這個時候就有人要問了,既然你跟我說順序表借助于數組實現,那為啥不就當成數組呢。它們兩個的關系就類似于什么呢:
我相信基本上能跟編程打交道的,你說你自己一點也不玩游戲,我是不信的,甭管玩手機游戲還是電腦游戲,你要玩游戲最基本得有個設備吧,就說手機游戲,你弄個平板玩,正常就摟著玩就行了唄,但是有的人嫌舉著累,買個支架,又嫌自己打游戲的時候發熱會導致掉幀,卡的不行,又買了一個散熱器,手老出汗買個指套,更有甚者玩個手機游戲開加速器。

順序表和數組基本就是這樣的,數組只能存一系列數據,你存著只能取出來用,對里面的數據進行增刪改是很麻煩的,順序表在創建好以后,相當于數組+增加/刪除/修改/查找……一系列的輔助工具,幫助你對數據進行維護,數組就沒有這個條件。

3.順序表的聲明

①靜態順序表

靜態數據表就是用定長數組來存儲數據的,當然,并不等同于數組,一般都是這樣定義的:

#define定義是為了方便修改靜態順序表的大小,即底層的數組的大小,為什么要將數組的類型由typedef定義一下呢,直接寫個int不行嗎?

給順序表的數據的類型取別名也是為了方便修改順序表所存儲的數據類型。

這樣看來順序表也沒比數組好到哪去,只不過可以確定有效數據個數而已。

這么看當然看不出來順序表相對于數組的優點,因為正常情況下,比如用順序表來存儲雙11某用戶的訂單個數,這種玩意肯定是動態的,不能說你就給他7個大小的內存,假如就說成7個訂單,那萬一雙十一買的多了咋辦,難道還能讓用戶少買一點嗎?肯定是用戶創建的訂單決定數據存儲的大小,也就是經常用的就是動態順序表。

②動態順序表

動態和靜態的區別在哪里那,其實舉的小例子已經給出了,靜態的順序表存儲的數據個數是固定的,你給少了吧就不夠用,給多了吧,又給內存浪費了(不要小看內存浪費,一個人浪費1000個字節,人多起來再多的內存都不夠用)。

千萬不要說,那你說要多大,比如存7個int,我就給你#define N 7,你要幾我就定義幾,這真就是對程序的內存申請不了解啊,在C語言學習的時候不說別的,編譯的時候就給這個順序表的內存大小固定死了,你把N定義的值改了有什么用,你程序已經寫好了,軟件里就是這么大,你說改成9,那么軟件就不能用了,就得重新把你改好的應用到軟件里,你敢想象雙十一,特別是雙十一的晚上購物平臺提交不了訂單會造成多大的損失嗎,等你改好再上架,黃花菜都涼了。

因此,來看我們動態順序表的聲明(動態就是可以根據你給的數據,去調整申請的內存大小)。

因為要動態申請,所以提前準備一個指針,去接收不管是malloc還是calloc等去申請的那塊內存空間的地址,有效數據個數不用多說,而靜態順序表的大小是確定的,動態順序表只能動態計算去確定,因此多加一個capacity變量。

4.動態順序表的初始化

聲明好一個變量做的第一件事就是初始化,創建一個順序表也是如此:

信心滿滿的寫完了,然后:

???

你這破計算機犯什么毛病,我已經第六行就是給你初始化去的,你告訴我未初始化干嘛。

其實還是我們之前提過的一個問題,傳值調用和傳址調用。

傳值調用只是對實參的一個臨時拷貝,如果僅僅用于計算,無可厚非,但是如果想傳值用形參來實現修改實參的話,那還是想想算了。

形參的值不影響實參的值,出了函數還直接沒了。

如果相對實參進行修改,那還是傳地址過來吧,讓我順著地址給你修改:

又再次復習了一下,這次可就是傳值傳址調用的實例了,不再是空泛的硬憋出來的例子。

5.順序表的插入

尾插

比如這樣的數據:

想在尾部插入的話得有size吧,知道了size才能知道該插入的位置(即我們想象出來的下標),這塊內存空間的起始地址也得有吧,因此,干脆直接像初始化一樣,傳過來這個順序表的地址,你想去用這個順序表哪個成員就用哪個成員,最后另外寫出來一個參數,這個參數接收需要插入的元素:

當然,這么寫就是錯的,順序表只初始化是沒有對應的內存空間的,并沒有給這個順序表申請空間,是不能去賦值的,所以在此之前先懟一個內存開辟,由于考慮到內存可能溢出的問題,所以malloc calloc realloc用realloc,這樣如果第一次開辟的內存不夠用,可以自主開辟:

realloc第一個參數如果是NULL的話,效果和malloc是一樣的,因為需要修改的位置為空,那么就不需要修改,直接開辟即可,返回值仍需檢查。

調試結果就是這樣的,其實挺簡單的。

頭插

這個有兩個要注意的點,一個是頭插必須把已有的數據后移,空出來順序表最前面的位置;后移必后面的先移,不然就會導致數據的覆蓋:

最后空出來的賦值就簡單了,下面是代碼表達:

調試沒問題:

指定位置插入

其實如果空想的話,你給我的下標是幾,那我就把這個下標開始加上后面的全部都后移,最后在這個位置插入你想插的元素:

真是服了,寫出來一大堆亂碼,檢查了半天是因為自己在擴容的時候寫錯了:

我算出來的newcapacity是元素個數,人家realloc要的是字節數,還得乘一下,調試半天。

其它沒什么疑問:

6.順序表的刪除

尾刪

直接給出

刪除操作,下意識的我們就可能想到,必須把尾部的數據給刪除了,但是實際上刪除以后難道計算機對于這塊位置就不再管了嗎?顯然不是的,只是變成亂碼了而已,假設給上亂碼,你不還是得size--嘛,反正也就是為了不再訪問順序表尾部的值,直接size--即可

頭刪

從前往后覆蓋即可:

比如這個,就是從2->1,3->2等等即可。

代碼表達:

測試:

一樣道理,即使最后的不刪,size為3,不管你做遍歷還是插入等一系列操作,都不會被這個值影響。

指定位置刪除

類似于頭插的前移,只不過與所給位置有關而已:

調試:

7.順序表的查找

參數肯定是一個順序表,一個需要查找的元素,不過這次僅僅是查找,可以傳值調用了,畢竟不要求對數據源進行修改,僅僅是對比。

調試:

8.順序表遍歷打印

當然,這里只寫int類型的遍歷:

調試:

毋庸置疑。

9.順序表的銷毀

如果你寫的是局部變量,那就等出了函數系統自動回收空間就算了,但是我們用的最多的是動態順序表,也就意味著有一塊動態開辟的內存空間,碰見這樣的事的話,用完了手動給它回收吧,不過我們要給它封裝成一個函數:

不用多解釋,其實就是調用了個free,最后置指針為空。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/80197.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/80197.shtml
英文地址,請注明出處:http://en.pswp.cn/web/80197.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

性能測試詳解

🍅 點擊文末小卡片,免費獲取軟件測試全套資料,資料在手,漲薪更快 一、什么是性能測試 先看下百度百科對它的定義 性能測試是通過自動化的測試工具模擬多種正常、峰值以及異常負載條件來對系統的各項性能指標進行測試 我們可以認為…

每日Prompt:三只動物與地標自拍磨砂玻璃后的虛實對比剪影

提示詞 一張黑白照片,展示了一個[主體]在磨砂或半透明表面后的模糊剪影。其[部分]輪廓清晰,緊貼表面,與其余朦朧、模糊的身影形成鮮明對比。背景是柔和的灰色漸變色調,增強了神秘和藝術的氛圍。

Android多媒體——媒體解碼器初始化(十五)

通過上一篇文章我們了解了媒體解碼器的創建過程,并且可以看到,在媒體解碼器創建成功后,分別調用了 configure()、setCallback() 和 start() 函數來對解碼器進行配置、回調和啟動。這里我們就來詳細看一下這幾個過程。 一、配置解碼器 首先看一下解碼器的配置,在 NuPlayerD…

每周資訊 | 騰訊Q1財報:國內游戲業務收入同比增長24%;Tripledot 8億美元收購AppLovin游戲業務

內容速覽: 廣州“服務貿易和數字貿易22條”助推游戲產業發展Tripledot Studios 8億美元收購AppLovin游戲業務蘋果緊急申請暫停執行AppStore新規4月中國手游出海收入下載榜,點點互動《Kingshot》收入激增 騰訊Q1財報:國內游戲業務收入同比增長…

本地跑通vue-element-admin項目

GitHub - PanJiaChen/vue-element-admin: :tada: A magical vue admin https://panjiachen.github.io/vue-element-admin 通過加速clone到本地 git clone https://gitclone.com/github.com/PanJiaChen/vue-element-admin.git # 進入項目目錄 cd vue-element-admin # 安裝依賴…

Go語言交替打印問題及多種實現方法

Go語言交替打印問題及多種實現方法 在并發編程中,多個線程(或 goroutine)交替執行任務是一個經典問題。本文將以 Go 語言為例,介紹如何實現多個 goroutine 交替打印數字的功能,并展示幾種不同的實現方法。 Go 語言相關…

支持藍牙5.0和2.4G私有協議芯片-PHY6222

PHY6222QC-W04C 是一款適用于藍牙低功耗(BLE)5.2 應用的片上系統(SoC)。它搭載 ARM Cortex?-M0 32 位處理器,配備 64KB SRAM、512K Flash、96KB ROM、256 bit efuse ,以及超低功耗、高性能的多模式射頻模塊…

git相關配置

git相關配置 歡迎使用Markdown編輯器修改Git默認編輯器為vimgit配置默認用戶名和密碼: 歡迎使用Markdown編輯器 修改Git默認編輯器為vim #方法1:直接執行 git config --global core.editor vim#方法2:修改git的配置文件.git/config文件&am…

C語言實現INI配置文件讀取和寫入

一.INI文件介紹 INI配置文件是一種簡單的文本文件,用于存儲配置信息,通常由一個或多個節(section)組成,每個節包含多個鍵值對(Key-Value)格式。INI文件易于閱讀和編輯,廣泛應用于多…

Vue 3 打開 el-dialog 時使 el-input 獲取焦點

運行代碼:https://andi.cn/page/622178.html 效果:

【程序員AI入門:模型】19.開源模型工程化全攻略:從選型部署到高效集成,LangChain與One-API雙劍合璧

一、模型選型與驗證:精準匹配業務需求 (一)多維度評估體系 通過量化指標權重實現科學選型,示例代碼計算模型綜合得分: # 評估指標權重與模型得分 requirements {"accuracy": 0.4, "latency": …

卡頓檢測與 Choreographer 原理

一、卡頓檢測的原理 卡頓的本質是主線程(UI 線程)未能及時完成某幀的渲染任務(超過 16.6ms,以 60Hz 屏幕為例),導致丟幀(Frame Drop)。檢測卡頓的核心思路是監控主線程任務的執行時…

物聯網僵尸網絡防御:從設備認證到流量染色

一、IoT設備的安全困境 典型物聯網設備存在硬編碼密鑰問題: // 固件中的危險代碼示例 const char* DEFAULT_KEY "A1B2-C3D4-E5F6"; // 廠商預設密鑰 void connect_server() {authenticate(DEFAULT_KEY); // 密鑰從未更新 }此類漏洞導致某智能家居平臺…

二叉樹子樹判斷:從遞歸到迭代的全方位解析

一、題目解析 題目描述 給定兩棵二叉樹root和subRoot,判斷root中是否存在一棵子樹,其結構和節點值與subRoot完全相同。 示例說明 示例1: root [3,4,5,1,2],subRoot [4,1,2] 返回true,因為root的左子樹與subRoot完…

Springboot 異步場景 使用注解 @Async 及 自定義線程池分模塊使用

目錄 前言一、Springboot項目如何開啟異步?二、存在的問題三、自定義線程池四、自定義線程池使用五、阻塞隊列和拒絕策略 前言 當開發中遇到不影響主流程任務時,使用異步去處理。 如有以下場景: 1、業務需要生成一個季度的數據進行員工排名&…

【GNN筆記】Signed Graph Convolutional Network(12)【未完】

視頻鏈接:《圖神經網絡》 Signed Graph Convolutional Network 之前介紹的GNN模型主要集中在無符號的網絡(或僅由正鏈接組成的圖)上,符號 圖帶來的挑戰,主要集中在于 否定鏈接,與正鏈接相比,它不…

米勒電容補償的理解

米勒電容補償是使運放放大器穩定的重要手法,可以使兩級運放的兩個極點分離,從而可以得到更好的相位裕度。 Miller 電容補償的本質是增加一條通路流電流,流電流才是miller效應的本質。給定一個相同的輸入,Miller 電容吃掉的電流比…

CVE-2017-8046 漏洞深度分析

漏洞概述 CVE-2017-8046 是 Spring Data REST 框架中的一個高危遠程代碼執行漏洞&#xff0c;影響版本包括 Spring Data REST < 2.5.12、2.6.7、3.0 RC3 及關聯的 Spring Boot 和 Spring Data 舊版本。攻擊者通過構造包含惡意 SpEL&#xff08;Spring Expression Language&…

qt文本邊框設置

// 計算文本的大致尺寸 QFontMetrics fm(textEditor->font()); QRect textRect fm.boundingRect(textItem->toPlainText()); // 設置編輯框大小&#xff0c;增加一些邊距 const int margin 10; textEditor->setGeometry( center.x() - textRect.width()/2 - margin,…

Java 與 面向對象編程(OOP)

Java 是典型的純面向對象編程語言&#xff08;Pure Object-Oriented Language&#xff09;&#xff0c;其設計嚴格遵循面向對象&#xff08;OOP&#xff09;的核心原則。以下是具體分析&#xff1a; 1. Java 的面向對象核心特性 (1) 一切皆對象 Java 中幾乎所有的操作都圍繞…