单链表删除所有值为x的元素_C/C++编程笔记:如何使用C++实现单链表?单链表的基本定义...
如何彌補(bǔ)順序表的不足之處?
第一次學(xué)習(xí)線性表一定會(huì)馬上接觸到一種叫做順序表(順序存儲(chǔ)結(jié)構(gòu)),經(jīng)過(guò)上一篇的分析順序表的優(yōu)缺點(diǎn)是很顯然的,它雖然能夠很快的訪問(wèn)讀取元素,但是在解決如插入和刪除等操作的時(shí)候,卻需要移動(dòng)大量的元素,效率較低,那么是否有一種方法可以改善或者解決這個(gè)問(wèn)題呢?
首先我們需要考慮,為什么順序表中的插入刪除操作會(huì)涉及到元素的移動(dòng)呢?
好家伙,問(wèn)題就是圍繞著順序表的最大的特點(diǎn)出現(xiàn)的——順序存儲(chǔ),相鄰放置元素,也就是說(shuō)每個(gè)元素都是根據(jù)編號(hào)一個(gè)一個(gè)挨著的,這就導(dǎo)致了 插入或刪除后,為了仍然呈順序線性存儲(chǔ),被操作元素后面的元素的位置均需要發(fā)生一定的變化,你應(yīng)該能想象得到,在擁擠的隊(duì)伍中突然從中插入一個(gè)學(xué)生的場(chǎng)景,后面浩浩蕩蕩的人群,口吐芬芳的向后挪了一個(gè)空位,如果人群過(guò)大,重新排好隊(duì)也需要一定的時(shí)間
好嘛,人與人之間別這么擠在一起,每個(gè)人與人之間都留出一點(diǎn)空隙來(lái),留一定的位置出來(lái),好了,這好像是個(gè)辦法,但是負(fù)責(zé)一個(gè)一個(gè)與學(xué)生交流填表的老師可就不干了,這意味著我(找人)遍歷的時(shí)候,需要多跑好多路,浪費(fèi)好多時(shí)間,先不說(shuō)這個(gè),體院館又不行了,你們這么個(gè)擺法,我這小館可放不下,這也就意味著空間復(fù)雜度增加了很多。
我們剛才所圍繞的都是在 "排隊(duì)" 的基本前提下的,但我們能想到的方法并不是很理想,那么我們索性就不排隊(duì)了,是不是能有更好的解決方式呢?
一個(gè)有效的方法:
讓同學(xué)們(元素)自己找位置隨便站,不過(guò)你要知道相對(duì)于自己下一位同學(xué)的位置,這樣既解決了空間上的問(wèn)題,又能通過(guò)這種兩兩聯(lián)系的方式訪問(wèn)(遍歷)到整個(gè)隊(duì)伍(數(shù)組),最重要的是,插入和離開(kāi)同學(xué),由于同學(xué)(元素)之間不存在了那種排隊(duì),相鄰的特點(diǎn),所以也不會(huì)說(shuō)影響到過(guò)多的同學(xué)(元素)只需要和你插入位置的前后兩位同學(xué)溝通好就行了,反正別人也不知道你們之間發(fā)生了什么事
好了思路是有了,我們來(lái)看一種最常見(jiàn)的鏈表——單鏈表
單鏈表的基本結(jié)構(gòu)
這種鏈表為什么被稱(chēng)作單鏈表呢?這是因?yàn)樗缓幸粋€(gè)地址域,這是什么意思呢?
我們?cè)阪湵碇袛P棄了順序表中那種一板一眼的排隊(duì)方式,但是我們必須讓兩個(gè)應(yīng)該相鄰的元素之間有一定的相互關(guān)系,所以我們選擇讓每一個(gè)元素可以聯(lián)系對(duì)應(yīng)的下一個(gè)元素
而這個(gè)時(shí)候我們就需要給每個(gè)元素安排一個(gè)額外的位置,來(lái)存儲(chǔ)它的后繼元素的存儲(chǔ)地址,這個(gè)存儲(chǔ)元素信息的域叫做指針域或地址域,指針域中儲(chǔ)存的信息也叫做指針或者鏈,
我們用一張圖 看一下他的結(jié)構(gòu)
結(jié)構(gòu)中名詞解釋
頭指針:一個(gè)指向第一個(gè)節(jié)點(diǎn)地址的指針變量
頭指針具有標(biāo)識(shí)單鏈表的作用,所以經(jīng)常用頭指針代表單鏈表的名字
頭結(jié)點(diǎn):在單鏈表的第一個(gè)結(jié)點(diǎn)之前附設(shè)一個(gè)結(jié)點(diǎn),它沒(méi)有直接前驅(qū),稱(chēng)之為頭結(jié)點(diǎn)
可不存信息,也可以作為監(jiān)視哨,或用于存放線性表的長(zhǎng)度等附加信息
指針域中存放首元結(jié)點(diǎn)的地址
首元結(jié)點(diǎn):存儲(chǔ)第一個(gè)元素的節(jié)點(diǎn)
為什么要附設(shè)一個(gè)頭結(jié)點(diǎn)
我們來(lái)解釋一下:
(1)鏈表如果為空的情況下,如果單鏈表沒(méi)有頭結(jié)點(diǎn),那么頭指針就會(huì)指向NULL,如果加上頭結(jié)點(diǎn),無(wú)論單鏈表是否為空,頭指針都會(huì)指向頭結(jié)點(diǎn),這樣使得空鏈表與非空鏈表處理一致
(2)使首元結(jié)點(diǎn)前插入或刪除元素的時(shí)候,與后面操作相同,不需要產(chǎn)生額外的判斷分支,使得算法更加簡(jiǎn)單
(以插入為例講解)在帶頭結(jié)點(diǎn)的情況下,在首元結(jié)點(diǎn)前插入或者刪除元素仍與在其他位置的操作相同,只需要將前一個(gè)元素(在這里是頭結(jié)點(diǎn))的指針域指向插入元素,同時(shí)將插入元素的指針域指向原來(lái)的第二的元素
而無(wú)頭結(jié)點(diǎn)的情況由于,首元結(jié)點(diǎn)前沒(méi)有元素,只能通過(guò)修改head的前后關(guān)系,所以導(dǎo)致了 與在別的位置插入或刪除元素的操作不同,在實(shí)現(xiàn)這兩個(gè)功能的時(shí)候就需要額外的寫(xiě)一個(gè)判斷語(yǔ)句來(lái)判斷插入的位置是不是首元結(jié)點(diǎn)之前的位置,增加了分支,代碼不夠簡(jiǎn)潔
總結(jié):頭結(jié)點(diǎn)的存在使得空鏈表與非空鏈表處理一致,也方便對(duì)鏈表首元結(jié)點(diǎn)前結(jié)點(diǎn)的插入或刪除操作
單鏈表的類(lèi)型定義
###線性表的抽象數(shù)據(jù)類(lèi)型定義
我們?cè)诮o出單鏈表的定義之前我們還是需要先引入我們線性表的抽象數(shù)據(jù)類(lèi)型定義
單鏈表的類(lèi)型定義
單鏈表上的基本運(yùn)算實(shí)現(xiàn)
(一) 單鏈表的初始化-構(gòu)造函數(shù)
單鏈表的初始化就是創(chuàng)建一個(gè)帶頭節(jié)點(diǎn)的空鏈表,我們不需要設(shè)置其指針域,為空即可
注意:new 操作符代表申請(qǐng)堆內(nèi)存空間,上述代碼中應(yīng)該判斷是否申請(qǐng)成功,為簡(jiǎn)單,默認(rèn)為申請(qǐng)成功,實(shí)際上如果系統(tǒng)沒(méi)有足夠的內(nèi)存可供使用,那么在申請(qǐng)內(nèi)存的時(shí)候會(huì)報(bào)出一個(gè) bad_alloc exception 異常
(二) 析構(gòu)函數(shù)
當(dāng)單鏈表對(duì)象脫離其作用域時(shí),系統(tǒng)自動(dòng)執(zhí)行析構(gòu)函數(shù)來(lái)釋放單鏈表空間,其實(shí)也就是清空單鏈表內(nèi)容,同時(shí)釋放頭結(jié)點(diǎn)
(三) 清空單鏈表
清空單鏈表的主要思想就是從頭節(jié)點(diǎn)開(kāi)始逐步將后面節(jié)點(diǎn)釋放掉,但是我們又不想輕易的修改頭指針head的指向,所以我們引入一個(gè)工作指針,從頭結(jié)點(diǎn)一直移動(dòng)到表尾,逐步釋放節(jié)點(diǎn)
下節(jié)知識(shí)分享我們將會(huì)講到,如何求單鏈表的表長(zhǎng)以及遍歷單鏈表、插入,刪除節(jié)點(diǎn)等方法的實(shí)現(xiàn),記得關(guān)注哦~
自學(xué)C/C++編程難度很大,不妨和一些志同道合的小伙伴一起學(xué)習(xí)成長(zhǎng)!
C語(yǔ)言C++編程學(xué)習(xí)交流圈子,關(guān)注+私信【C/C++編程】微信公眾號(hào):C語(yǔ)言編程學(xué)習(xí)基地
有一些源碼和資料分享,歡迎轉(zhuǎn)行也學(xué)習(xí)編程的伙伴,和大家一起交流成長(zhǎng)會(huì)比自己琢磨更快哦!
總結(jié)
以上是生活随笔為你收集整理的单链表删除所有值为x的元素_C/C++编程笔记:如何使用C++实现单链表?单链表的基本定义...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python库_计算机二级教程 Pyt
- 下一篇: c++图书管理系统_轻松学做C语言课程设