3atv精品不卡视频,97人人超碰国产精品最新,中文字幕av一区二区三区人妻少妇,久久久精品波多野结衣,日韩一区二区三区精品

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构 | 单链表SingleList【带你从浅入深真正搞懂链表】

發(fā)布時間:2023/12/10 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构 | 单链表SingleList【带你从浅入深真正搞懂链表】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

寫在前面

  • 很多粉絲經(jīng)常私信問我有關(guān)指針、鏈表相關(guān)的問題,也非常希望我出一篇有關(guān)鏈表的教學(xué),最近剛好也在整理有關(guān)單鏈表相關(guān)的知識點,便作了此文,為大家講解有關(guān)單鏈表方面的各塊知識點。
  • 本文考慮到閱讀者的水平和能力,內(nèi)容有深有淺,總體講解主要是從淺入深循序漸進(jìn)地闡述有關(guān)鏈表相關(guān)的知識

鏈表真的很難嗎?

  • 一、前言
    • 1、順序表的缺陷【生活小案例1——盛20粒米飯🍚】
    • 2、優(yōu)化方案
  • 二、鏈表的初步認(rèn)知
    • 1、結(jié)構(gòu)的聲明與定義
    • 2、棧區(qū)存放與堆區(qū)存放
    • 3、開始鏈接結(jié)點啦🎉【邏輯結(jié)構(gòu)與物理結(jié)構(gòu)的區(qū)分】
    • 4、運行起來了,開始玩鏈表
      • 打印鏈表【生活小案例2——王思聰不需要省錢】
      • 函數(shù)調(diào)用棧幀圖【?庖丁解牛,細(xì)致剖析】
  • 三、接口算法實現(xiàn)【是時候表演真正的技術(shù)了🆒】
    • 1、尾插【Hard】
      • 經(jīng)典錯誤案例分析
      • 二級指針真正改變頭結(jié)點的指向【?????】
    • 2、尾刪【Circuitous】
      • 經(jīng)典錯誤案例分析
      • 修改方式一:保存ptail的上一個結(jié)點
      • 修改方式二:ptail->next->next
      • 特殊情況修正【單個結(jié)點、二級指針修改、斷言報錯】
    • 3、頭插【Easy】
    • 4、頭刪【Easy】
    • 5、查找
    • 6、在pos位置之后插入結(jié)點
      • 警惕傳入空指針【?細(xì)致講解斷言assert】
      • 【生活小案例3——請人吃飯要帶錢💴】
    • 7、在pos位置之前插入結(jié)點
    • 8、刪除pos位置之后的結(jié)點
      • 野指針的危害【生活小案例4——酒店房門的鑰匙🔑】
    • 9、刪除pos位置之前的結(jié)點
    • 10、釋放鏈表
      • 【生活小案例5——利劍不鋒利🗡】
  • 四、整體代碼展示【需要自取】
  • 五、有關(guān)二級指針和斷言的小結(jié)【?謹(jǐn)記?】
  • 六、OJ題目實訓(xùn)
    • 【LeetCode】21 - 合并兩個有序鏈表
    • 【LeetCode】203 - 移除鏈表元素
    • 【LeetCode】206 - 反轉(zhuǎn)鏈表
    • 【LeetCode】876 - 鏈表的中間結(jié)點
    • 【牛客CM】11 - 鏈表分割
    • 【牛客JZ】22 - 鏈表中倒數(shù)第k個結(jié)點
  • 七、總結(jié)與提煉

一、前言

1、順序表的缺陷【生活小案例1——盛20粒米飯🍚】

缺陷1:空間經(jīng)常會不夠,需要擴(kuò)容

  • 在上一節(jié),我們講到了順序表基本函數(shù)結(jié)構(gòu)的算法實現(xiàn),說到了順序表其實和數(shù)組本質(zhì)差不多,存放的數(shù)據(jù)都是連續(xù)的,但是通過一些頭插、尾插和萬能插入可以看出順序表在有些情況下可能會出現(xiàn)空間不夠,需要擴(kuò)容的操作,而且對于擴(kuò)容機(jī)制,我們上次講到了【本地擴(kuò)容】和【異地擴(kuò)容】,尤其是對于異地擴(kuò)容,需要先釋放掉原先存放的地址,然后再去異地申請一塊地址,這其實是需要一定代價的
  • 對于擴(kuò)容的大小來說,一擴(kuò)就是原來的2倍,這些擴(kuò)出來的2倍我們不一定都能使用得完,所以就存在一定的空間浪費。那有同學(xué)說你怎么知道會用不完呢,萬一我用完了呢,其實這你我都不敢肯定自己需要使用多大的空間,只是知道現(xiàn)在的空間不夠了,需要再申請一些空間
  • 這其實就是我們吃飯的時候吃了一碗不夠需要再去盛一碗是一樣的,那一碗不夠你可能就會去盛兩碗,但是有點時候兩碗又吃不完(能吃完的請忽略😄),所以這個時候我們就會選擇少盛一點,但是盛少了又不夠吃,如果給你盛1碗20粒米飯這多出來的20粒米你覺得真的夠吃嗎,所以你還會再去盛。所以要盛多少呢?這就好比我們?nèi)ド暾埧臻g,若是申請得太少了,就可能需要頻繁地再去申請,但若是申請得太多了就會用不完,浪費

缺陷2:插入或刪除數(shù)據(jù)時需要挪動大量數(shù)據(jù),效率低下

  • 雖然有了萬能插入,但是我們前面在寫頭插、尾插、頭刪、尾刪的時候花了不少的功夫去解決這些難題,對于頭插,需要將數(shù)據(jù)從后往前一一后移;對于頭刪,需要將數(shù)據(jù)從前往后一一前移,這兩種情況就是插入和刪除中最壞的兩種,時間復(fù)雜度接近O(N),因此我們可以看出對于順序表它還具有一大缺陷就是對于數(shù)據(jù)的插入和刪除需要挪動大量的數(shù)據(jù),因為時間復(fù)雜度的過高,導(dǎo)致效率的低下

2、優(yōu)化方案

因為我們就應(yīng)該對這兩種缺陷做一個改進(jìn)

  • 對于空間不夠需要擴(kuò)容的情況,我們可以使用動態(tài)申請,就像動態(tài)順序表那樣使用malloc來申請所需要的空間,需要存儲一個數(shù)據(jù)就開一塊空間,在本節(jié)要介紹的【鏈表】中,叫做【結(jié)點】,當(dāng)然有些書上寫叫做【節(jié)點】,這個都可以,沒有區(qū)別,隨你怎么叫。
  • 對于增刪需要挪動大量數(shù)據(jù)的情況,我們可以使用一種手段將前后兩個結(jié)點之間做一個聯(lián)系,也就是前一個結(jié)點存放下一個結(jié)點在堆區(qū)中申請的那塊內(nèi)存地址,也就是我們在C語言中所學(xué)到的指針可以存放一塊地址,這樣就使得前一個結(jié)點和后一個結(jié)點產(chǎn)生了一定的關(guān)聯(lián)。然后當(dāng)我們需要去插入或者刪除數(shù)據(jù)時,只需要修改當(dāng)前結(jié)點所存放的內(nèi)存地址即可,修改了所存放的地址值,這個時候便與新的結(jié)點產(chǎn)生了聯(lián)系

對于鏈表這一塊,如果C語言的指針和結(jié)構(gòu)體這一塊你沒有很熟悉的話,學(xué)起來確實會比較困難,但這也不妨礙你看本文,我一定會慢慢地帶你從淺到深,去領(lǐng)會鏈表該如何操作

二、鏈表的初步認(rèn)知

1、結(jié)構(gòu)的聲明與定義

  • 首先里看一下鏈表的結(jié)構(gòu),它的每一個結(jié)點因為要存放數(shù)據(jù)和下一個結(jié)點的地址,因此需要一個數(shù)據(jù)域、一個指針域,如下圖所示👇

  • 了解了鏈表的結(jié)構(gòu)體是如何的,接下來我們用代碼的形式將其展現(xiàn)出來
  • 可以看到,這里數(shù)據(jù)域的類型是單獨typedef的,這個在順序表中講過,因為每一個數(shù)據(jù)可能并不是整型的,可能是char、long或者是double類型。對于next指針域,你可以看到其為一個結(jié)構(gòu)體指針類型,因為這個next指針,它指向的下一個結(jié)點又是一個封裝好的結(jié)構(gòu)體。
typedef int SLTDataType; typedef struct SListNode { //結(jié)構(gòu)體大小:8BSLTDataType data;struct SListNode* next;//SLTNode* next; 不可以這樣定義,因為還沒有到聲明 }SLTNode;
  • 此處的結(jié)構(gòu)體類型我們也進(jìn)行了一個typedef,但是當(dāng)這個結(jié)構(gòu)體聲明出來后,有同學(xué)就把這個next指針的類型就定義成了typedef后的類型,這個是不對的,如果你這樣定義,那說明你的結(jié)構(gòu)體學(xué)的不扎實,這是一種錯誤的定義方式,此處的SLTNode還沒有聲明出來,所以是不可以使用的
  • 它的定義格式實際上是這樣的,當(dāng)你去使用SLTNode定義next指針時,它還沒有被聲明出來
typedef int SLTDataType; struct SListNode { //結(jié)構(gòu)體大小:8BSLTDataType data;struct SListNode* next; }; typedef struct SListNode SLTNode;

2、棧區(qū)存放與堆區(qū)存放

明白了如何去定義一個結(jié)構(gòu)體,接下去我們就用這個定義的結(jié)構(gòu)體試著去創(chuàng)建一兩個結(jié)點,然后對它們進(jìn)行一個鏈接,我用了下面兩種定義和鏈接方法,你覺得哪個更好呢?

第一種,指針類型【動態(tài)開辟】

SLTNode* n1 = (SLTNode*)malloc(sizeof(SLTNode)); SLTNode* n2 = (SLTNode*)malloc(sizeof(SLTNode)); n1->next = n2;

第二種,變量類型【直接定義】

SLTNode n3, n4; n3.next = &n4;
  • 那有小伙伴可能就被難住了,接下來聽我給你說說👊
  • 對于鏈表,當(dāng)我們?nèi)ザx一個個結(jié)點進(jìn)行插入的時候,都是希望在最后能將這些結(jié)點鏈接成為一個鏈?zhǔn)奖硪粯?#xff0c;所以想讓它保存在最后。但是第二種直接定義的變量類型卻做不到這一點,這樣的定義方式屬于一種局部變量的定義,對于局部變量的定義,是在內(nèi)存中的【棧區(qū)】為其開辟空間的,這就我們常說的【棧幀】,函數(shù)中的變量定義就需要消耗一定的棧幀,但你這個函數(shù)結(jié)束之后,那這個棧幀也就銷毀了,此時你辛辛苦苦鏈接起來的鏈表中各個結(jié)點的數(shù)據(jù)也就隨著棧幀的銷毀而蕩然無存了,這其實就相當(dāng)于是出Bug了
  • 但若是用上面一種定義方式去弄的話,就不會造成這樣的現(xiàn)象,之前我們有說到過,對于動態(tài)申請的空間,是存放在內(nèi)存【堆區(qū)】中的,而對于堆區(qū)中存放的內(nèi)容,是到程序結(jié)束才會銷毀,而且上面提到,對于每一個鏈表結(jié)點,我們最好使用動態(tài)開辟的方式是申請空間,這樣的彈性就更加大一些,不會像順序表那樣需要不斷地擴(kuò)容

3、開始鏈接結(jié)點啦🎉【邏輯結(jié)構(gòu)與物理結(jié)構(gòu)的區(qū)分】

  • 明白了要使用malloc去動態(tài)開辟結(jié)點,將其存放在【堆區(qū)】中,接下去就開辟幾個結(jié)點,然后將他們進(jìn)行一個鏈接
SLTNode* BuySLTNode(SLTDataType x) {//動態(tài)開辟SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("malloc fail\n");exit(-1);}newnode->data = x;newnode->next = NULL; }
  • 可以看到,這里我將動態(tài)開辟一塊空間并且初始化結(jié)點值封裝成了一個叫【BuySLTNode】的函數(shù),也就是得到一個鏈表結(jié)點,最后用一個鏈表結(jié)構(gòu)體類型去接收一下,就有了四個結(jié)點值,最后將他們一一鏈接起來即可🔒
SLTNode* n1 = BuySLTNode(1); SLTNode* n2 = BuySLTNode(2); SLTNode* n3 = BuySLTNode(3); SLTNode* n4 = BuySLTNode(4); n1->next = n2; n2->next = n3; n3->next = n4; n4->next = NULL;
  • 那個這四個結(jié)點在你腦海中鏈接起來是什么樣子的呢,我想一定是下面這種樣子,每個結(jié)點對應(yīng)一個變量,然后其next指針域使用一個箭頭符號指向下一個結(jié)點

  • 這是大多數(shù)人的思維,但是在計算機(jī)實際的內(nèi)存中,可不是這樣存儲的,真正的物理結(jié)構(gòu)是下面這樣
  • 當(dāng)你申請出了一塊空間,然后初始化這個結(jié)點的值并且用一個結(jié)構(gòu)體鏈表結(jié)點去接收的時候,這個n1,n2,n3,n4并不是普通的變量,而是一個指針變量,一個結(jié)構(gòu)體指針變量,既然是指針那就一定指向一塊內(nèi)存地址,也就是我們在Buy一個結(jié)點的時候為這個結(jié)點所申請的這塊內(nèi)存地址,而當(dāng)你去解引用這個指針變量時,也就拿到了這塊內(nèi)存的地址值,這其實就可以解釋了為什么n1->next = n2,是等于n2,而不是一個內(nèi)存地址值,因為這個n2中存放的就是當(dāng)前這個結(jié)點在堆區(qū)中申請的這塊地址
n1->next = n2; n2->next = n3; n3->next = n4; n4->next = NULL;
  • 接下去我解釋一下這些結(jié)點之間的聯(lián)系,對于這些結(jié)點我們上面說過了,具有一個數(shù)據(jù)域和一個指針域,對于指針域,它與下一個結(jié)點之間的關(guān)系其實并不是用一個箭頭去指向的,當(dāng)然下面的這張圖我只是為了更加形象,當(dāng)前結(jié)點指針域與下一個結(jié)點之間的關(guān)系應(yīng)該是當(dāng)前結(jié)點指針域存放下一個結(jié)點在堆區(qū)中申請的內(nèi)存地址

  • 那這么說可能還是不太直觀,我們進(jìn)編譯器中去DeBug一探究竟🔍
  • 可以看出,確實是這樣,這下你應(yīng)該有所理解了吧

4、運行起來了,開始玩鏈表

搞清楚了鏈表的各個結(jié)點直接是如何前后鏈接起來的,接下去我們正式地來玩一玩💷,申請多個結(jié)點將他們串起來

SLTNode* BuySLTNode(SLTDataType x) {//動態(tài)開辟SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("malloc fail\n");exit(-1);}newnode->data = x;newnode->next = NULL; } SLTNode* SListCreate(int n) {SLTNode* phead = NULL, * ptail = NULL;for (int i = 0; i < n; ++i){SLTNode* newnode = BuySLTNode(i);if (phead == NULL)phead = ptail = newnode;else{ptail->next = newnode;ptail = newnode;}}return phead; }
  • 解釋一下新寫的這段邏輯,通過傳進(jìn)來需要構(gòu)建的n個結(jié)點,我們需要通過循環(huán)去一一搭建,那我們就需要使用到構(gòu)建鏈表的一個很重要邏輯——尾插法,首先我們要去定義一個頭結(jié)點指針和一個尾結(jié)點指針,對于鏈表,有帶頭結(jié)點和不帶頭結(jié)點的類型,后面我們會詳細(xì)介紹。對于這個頭結(jié)點指針phead,就是用來保存頭結(jié)點的,對于這個ptail尾結(jié)點指針,就是用來鏈接數(shù)據(jù)的,將每一個待插入的結(jié)點鏈接到當(dāng)前尾結(jié)點指針的后一個結(jié)點,也就是執(zhí)行這句
ptail->next = newnode; ptail = newnode;
  • 我們通過圖示來看一下



  • 可以看到,這通過ptail的移動,newnode被不斷插入到鏈表的后面,但是phead卻沒有變化,始終守護(hù)在頭結(jié)點的身邊👼,最后當(dāng)你想要觀看整個鏈表的結(jié)構(gòu)時,去獲取這個頭結(jié)點即可,因為后面的結(jié)點都是鏈接在頭結(jié)點之后的,所以頭結(jié)點不可以變化,一旦變化了那么整個鏈表的結(jié)構(gòu)就亂了😂,最后這是個函數(shù),返回值類型是LSTNode*,因此返回phead,主函數(shù)中去接收一下即可
  • 也就是這個SList,因為當(dāng)這個函數(shù)結(jié)束之后,所建立的棧幀也就跟著銷毀了,此時的phead就不復(fù)存在,但我們將其return返回了,那這個時候SList就保存了這個頭結(jié)點,之后便可以根據(jù)這個頭結(jié)點去訪問鏈表中的所有元素
SLTNode* SList = SListCreate(10);
  • 我們?nèi)eBug中看一下,從SList的數(shù)據(jù)結(jié)果來看,它確實獲取了整個鏈表的所有內(nèi)容😍

打印鏈表【生活小案例2——王思聰不需要省錢】

  • 通過畫圖和文字說明,懂得了鏈表存儲的邏輯以及使用頭結(jié)點去訪問整個鏈表,但我們還是看不見摸不著,接下去就進(jìn)行一個可視化,將這個鏈表打印出來看看
  • 我們一樣是本著這個不輕易改變頭結(jié)點的原則,定義一個結(jié)點指針去存放獲取這個頭結(jié)點,將phead的值給到一個cur的指針變量,然后的話就是我們熟悉的遍歷操作,上代碼??
void PrintList(SLTNode* phead) {SLTNode* cur = phead; //盡量不用頭指針,定義變量存放while (cur != NULL){printf("%d->", cur->data);cur = cur->next;}printf("NULL\n"); }
  • 那有同學(xué)還是搞不懂既然這個phead和cur都是相同的,那直接使用phead去遍歷不就好了,再定義一個結(jié)構(gòu)體指針又需要消耗內(nèi)存空間
  • 這里我就要和你普及一下有關(guān)內(nèi)存空間的大小的知識了,對于操作系統(tǒng)來說,這個內(nèi)存空間是很富裕的,在計算機(jī)內(nèi)存中1M = 10W(byte),1G = 10億(byte),對于一個cur結(jié)構(gòu)體指針的大小,也就是8個B的大小,對于系統(tǒng)來說完全就是芝麻粒小的東西,所以有沒有這個cur完全沒有影響。
  • 其實這么小一個cur對于操作系統(tǒng)來說和億萬富萬看待幾千塊錢是一個道理,那比如我們經(jīng)常在媒體娛樂中看到的王思聰,它爸爸就是萬達(dá)集團(tuán)的老總王健林,有一天王思聰和王健林說我這個月給您省了5千塊錢,但是他爸爸卻滿不在乎,因為這些前對他來說就是零花錢一般,省了和沒省也沒什么區(qū)別。
  • 那從這里就可以反映出對于編程時有些需要使用到的變量定義我們盡量還是不要省,可以起到它獨特的作用,比如說幫助理解程序,再者就是像我們這里的保護(hù)頭結(jié)點不被輕易改變

此時美麗的鏈表就被形象地打印了出來📷

  • 但是為了更加形象地讓大家看出鏈表的物理存儲結(jié)構(gòu),所以我這樣做👍
printf("[%d|%p]->", cur->data,cur->next);

函數(shù)調(diào)用棧幀圖【?庖丁解牛,細(xì)致剖析】

  • 我們可以看到,當(dāng)在Test函數(shù)中調(diào)用這個Create函數(shù)創(chuàng)建鏈表時,便對應(yīng)地開辟出了相應(yīng)的函數(shù)棧幀,對于Test函數(shù)和SListCreate函數(shù)都有它們自己單獨的棧幀,棧幀內(nèi)部就是函數(shù)體中定義的各種變量。因此在起初創(chuàng)建newnode的時候,phead和ptail均是指向這個鏈表的第一個結(jié)點,存了第一個結(jié)點的【地址】。phead是為了函數(shù)結(jié)束后返回,ptail則是為了鏈接
  • 對于函數(shù)而言,建立一個函數(shù)開辟棧幀,隨著函數(shù)的結(jié)束棧幀也就跟著銷毀了,這里的phead和ptail也不會存在,這就是我們?yōu)槭裁匆诙阎猩暾埧臻g去存放一個個結(jié)點,上面說到過,堆中申請的空間不會像棧中那樣,隨著函數(shù)的結(jié)束而被釋放,對于malloc動態(tài)開辟出來的空間是需要你去手動釋放的,也就是free()

  • 隨著新結(jié)點的插入,尾指針ptail不斷進(jìn)行移動,直至插入最后一個結(jié)點之后便結(jié)束插入,最后ptail是指向最后一個尾結(jié)點,phead是指向頭部第一個結(jié)點,【保存有整個鏈表的結(jié)構(gòu)】,最后將這個phead返回由函數(shù)外界的SList接收,便將Create函數(shù)中的建立的鏈表的頭拷貝給了SList,此時隨著Create函數(shù)的結(jié)束,所建立的棧幀也將銷毀,在函數(shù)內(nèi)部創(chuàng)建的局部變量也跟著一起銷毀,不復(fù)存在
  • 我們在C語言中講到過有【作用域】這么一個概念,任何變量,都有它的作用域:對于全局變量而言,它的作用域是從聲明開始到整個程序結(jié)束,但是對于局部變量而言,它的作用域也就是在其所聲明的函數(shù)內(nèi)部而已,出了作用域就銷毀了,但好在我們保存并返回了這個指向鏈表頭的指針,這個指針中又保存著第一個結(jié)點的地址,此時SList便可以通過這個地址去訪問這個鏈表

  • 當(dāng)這個SList獲取了鏈表頭結(jié)點的地址后,便將其傳入PrintList中,但是呢PrintList里是不可以使用外界的這個指針變量的,所以在函數(shù)形參部分,就定義了一個指針變量去接收,繼而就將這個鏈表頭結(jié)點指針?biāo)4娴牡刂房截惤o了這個phead的,這里的phead和Create中的phead又是不同的兩個東西,不要混淆。此時兩個獨立的函數(shù)棧幀中的指針變量就都指向堆區(qū)中的同一塊內(nèi)存地址
  • 上面說到過,為了不讓這個頭結(jié)點指針發(fā)生變動,就繼續(xù)定義了一個指針變量去進(jìn)行一個變量,從而打印出了這個鏈表的樣子

三、接口算法實現(xiàn)【是時候表演真正的技術(shù)了🆒】

認(rèn)真看完了上面兩個模塊,相信你對鏈表的整體框架和結(jié)構(gòu)已經(jīng)有了一個基本的認(rèn)識,現(xiàn)在我們要真正地去實現(xiàn)一些有關(guān)鏈表操作的接口,以便觀察鏈表這種數(shù)據(jù)結(jié)構(gòu)在處理數(shù)據(jù)的時候與順序表有何不同?

1、尾插【Hard】

  • 首先第一個我們就來看看尾插,這個在順序表中有講到過,就是在尾部插入一個數(shù)據(jù)結(jié)點,對于順序表來說很簡單,就是在size的位置放入這個元素接口,然后size++,但是對于鏈表來說,也會很容易嗎?我們一起來看看

經(jīng)典錯誤案例分析

void SListPushBack(SLTNode* phead, SLTDataType x) {SLTNode* newnode = BuySLTNode(x);SLTNode* ptail = phead; // while(tail != NULL)while (ptail) //一般寫成這樣{ptail = ptail->next;}ptail = newnode; //只是存放在局部變量中 }
  • 首先我給出一種很多同學(xué)常見的思路和寫法,也就是定義一個ptail指針從頭結(jié)點開始慢慢遍歷到最后為空的時候,然后把動態(tài)開辟出來的結(jié)點放到這個ptail中,這是很常見的一種錯誤,原理也是和我們上面講到過的函數(shù)棧幀的建立和銷毀一個道理,這里的ptail只是一個SListPushBack所在的棧幀中的一個局部變量而已,你讓它指向堆區(qū)新開辟出來的一塊空間,在函數(shù)內(nèi)部看起來是鏈接上了,但是當(dāng)這個函數(shù)結(jié)束時,所建立的棧幀便銷毀了,此時局部變量出了它的作用域也會跟著銷毀,所以這個尾部新插的結(jié)點newnode根本就沒有鏈接上
  • 對于尾插來說,它的本質(zhì)其實是讓最后一個結(jié)點鏈接新結(jié)點,也就是讓這個next去存放這塊堆區(qū)中申請的地址,這就是我們上面所說的物理結(jié)構(gòu)中結(jié)點與結(jié)點之間的關(guān)系

  • 所以應(yīng)該要像下面這么寫,去判斷ptail的next域是否為空,若為空則表示遍歷到了最后一個結(jié)點,此時應(yīng)該使用【 ptail->next = newnode】,讓ptail的next域指向這個新的結(jié)點才對
void SListPushBack(SLTNode* phead, SLTDataType x) {SLTNode* newnode = BuySLTNode(x);SLTNode* ptail = phead;while (ptail->next){ptail = ptail->next;}ptail->next = newnode; }
  • 當(dāng)然還有一種特殊情況就是這個單鏈表為空,那就要進(jìn)行一個單獨的判斷,然后讓phead指向這個新插入的結(jié)點newnode即可

void SListPushBack(SLTNode* phead, SLTDataType x) {SLTNode* newnode = BuySLTNode(x);if (phead == NULL){phead = newnode; //形參的改變不會影響實參}else{SLTNode* ptail = phead;while (ptail->next){ptail = ptail->next;}ptail->next = newnode;}}
  • 寫了這么一大堆,這回肯定是天衣無縫了,我們?nèi)y試一下吧
  • 哦哦,好像不太對誒😳,插入了三個數(shù)據(jù),但是完全沒有插進(jìn)去的樣子,這是為什么?我們來DeBug看一下

  • 可以看到在DeBug中,我們需要讓這個單鏈表形成的樣子應(yīng)該是第一次尾插的時候?qū)⑵渥鳛槭捉Y(jié)點,先進(jìn)去第一個if判斷,然后在后面兩次時都進(jìn)入下面的else判斷,但是當(dāng)我在調(diào)試的時候,發(fā)現(xiàn)每一次進(jìn)入的都是第一個if,也就意味著這個SList一直就是為空的,但是進(jìn)入函數(shù)內(nèi)部卻可以發(fā)現(xiàn)其實這個phead是指向了newnode所在的內(nèi)存地址的,但是在外面看的時候,這個SList卻始終都是空的,這是為什么呢?
  • 這就要說到C語言中的函數(shù)傳參問題了,我們知道,形參的改變是不會影響實參的,對于這個phead,就是SListPushBack中的形參,只是接收外界實參SList傳入的頭指針,也就是說phead所指向的地址并不代表SList也指向這塊地址,這和我們上面Create的時候不同,Create在創(chuàng)建出這個鏈表時會返回指向其頭部的head指針,外界可以接收到,但是在這里的尾插只是一個操作罷了,函數(shù)的返回值是void,因此外界根本無法從返回值來獲取和指向這個首部的指針
  • 那有同學(xué)說,這該怎么辦吶,好不容易寫出來了😢。我們繼續(xù)看下去


二級指針真正改變頭結(jié)點的指向【?????】

本模塊對于二級指針不太熟悉的同學(xué)先去看看二級指針有關(guān)的文章,我推薦這篇深入理解二級指針

  • 這個時候我們應(yīng)該聯(lián)想到C語言中有關(guān)指針方面很經(jīng)典的一道例題,就是交換兩個變量的值,我們來回顧一下這個代碼
void Swap1(int* p1, int* p2) {int tmp = *p1;*p1 = *p2;*p2 = tmp;} int a = 2, b = 5; printf("a = %d, b = %d\n", a, b); Swap1(&a, &b); printf("a = %d, b = %d\n", a, b);

  • 可以看到,兩個變量的值得到了交換,也就是很經(jīng)典的通過指針接收地址去交換兩個變量的值,我們先通過這個小案例帶大家DeBug一下

  • 可以看到,對于Swap1函數(shù),我們傳入了變量a和變量b的地址,然后在形參中,使用到兩個指針變量去接收這兩個地址,在函數(shù)體中,我們又可以通過【*p1和 *p2】解引的操作獲取變量a和變量b的內(nèi)容,引入第三方變量暫時存放一下,就可以實現(xiàn)一個交換了

  • 然后在Swap函數(shù)執(zhí)行完后,【*p1】和【*p2】的值進(jìn)行了一個交換

  • 當(dāng)這個Swap函數(shù)結(jié)束的時候,因為我們傳入的是兩個變量的地址,所以指針的解引直接是訪問這兩塊地址的內(nèi)容,因而就發(fā)生了一個交換


  • 好,有了這么一個引入,接下去我們將二級指針的傳參時就好理解一些了
  • 對于【int】型的變量,我們要交換改變它們的值需要對【int*】去傳入地址,拓展一下
  • 對于【int*】型的變量,我們要交換改變它們的值需要對【int**】去傳入地址,傳入什么地址呢,傳入的就是【int*】的地址
  • 這里的【int**】就是我們在C語言中學(xué)過的二級指針,接下去還是交換值,通過二級指針來看看如何進(jìn)行傳參交換
void Swap2(int** pp1, int** pp2) {int* tmp = *pp1;*pp1 = *pp2;*pp2 = tmp; } void test1() {int a = 2, b = 5;int* p1 = &a, * p2 = &b;printf("*p1 = %d, *p2 = %d\n", *p1, *p2);Swap2(&p1, &p2);printf("*p1 = %d, *p2 = %d\n", *p1, *p2); }
  • 可以看到,對于這里的變量a我首先通過一個指針變量p1去存放它的地址,對于變量b則是用p2存放,然后在Swap2中,傳入這兩個【一級指針變量】的地址,給到【二級指針變量】形參分別去接收它們的地址,我們繼續(xù)通過DeBug來看一下
  • 可以看到,pp1這個二級指針存放的是一級指針p1的地址;pp2同理存放p2的地址,
  • *pp1解引用將二級指針降為一級指針,使得 【*pp1 = p1】【 *pp2 = p2】,此時他們的指向都是相同的,存放的都是變量a和變量b的內(nèi)存地址
  • 拿一個【int*】類型的一級指針變量tmp去接收*pp1也就是一級指針p1,此時

  • 可以看到,讓Swap2函數(shù)結(jié)束時,*pp1和 *pp2這兩個一級指針的指向便發(fā)生了改變,然后通過解引用又改變了指向地址中所粗放的內(nèi)容

  • 結(jié)束函數(shù)回到test1()可以看到pp1和pp2這兩個二級指針都變灰了,這其實就是VS中所展現(xiàn)的函數(shù)調(diào)用結(jié)束內(nèi)部變量隨著棧幀的銷毀而被釋放,但是因為我傳入的p1與p2的這兩個一級指針的地址,所以函數(shù)內(nèi)部就相當(dāng)于獲取到了這兩個指針?biāo)赶虻牡刂?#xff0c;實現(xiàn)了一個同意操作,因此函數(shù)內(nèi)部的改變便帶動了外界的p1和p2指向的改變,由下圖便可看出
  • 然后從運行結(jié)果可以看到*p1和 *p2也就是 a 與 b值進(jìn)行了一個交換,這就實現(xiàn)了一個通過二級指針傳參來交換改變變量內(nèi)容的操作


但是我將這個二級指針有什么用呢?難道只是給你普及一下二級指針的知識嗎,那當(dāng)然不是,實際上就是為了通過這個二級指針接收以及結(jié)構(gòu)體指針SList去真正地通過內(nèi)部的修改改變外部的頭結(jié)點指針,我們通過代碼來看一下

//傳二級指針 void SListPushBack(SLTNode** pphead, SLTDataType x) {SLTNode* newnode = BuySLTNode(x);if (*pphead == NULL){*pphead = newnode;//通過二級指針的解引用改變頭結(jié)點【從NULL->newnode】}else{SLTNode* pptail = *pphead;while (pptail->next){pptail = pptail->next;//無需再使用二級指針,無需改變頭結(jié)點,只需要做一個鏈接//改變結(jié)構(gòu)體的指向,使用結(jié)構(gòu)體指針}pptail->next = newnode;} } SLTNode* SList = NULL; SListPushBack(&SList, 100); SListPushBack(&SList, 200); SListPushBack(&SList, 300); PrintList(SList);

  • 可以看到函數(shù)中的形參我使用的是一個二級指針,然后在test中,我將這個指向頭結(jié)點的一級指針SList的地址傳了進(jìn)去,當(dāng)?shù)谝淮挝膊暹@個100的時候,便會進(jìn)入第一個if分支,*pphead便是解引用之后的一級指針,就相當(dāng)于這個SList,因此當(dāng)你將新開辟的結(jié)點newnode插入時,便直接將【*pphead】指向了這塊堆區(qū)中的地址。然后在第二次插入200的時候,便會進(jìn)入第二個else分支,使用一個一級指針類型的指針變量pptail去接收【 *pphead】,不斷往后遍歷,然后將兩個結(jié)點通過【存放地址】的關(guān)系鏈接起來,就完成了我們的尾插操作
  • 有同學(xué)可能對下面這段else邏輯比較疑惑,為什么在修改頭結(jié)點的時候要用到二級指針,但是在后面的鏈接中不需要用到了呢?,這個時候就要去思考,因為在后驅(qū)的結(jié)點鏈接時只是做一個將當(dāng)前結(jié)點的next存放下一個結(jié)點在堆區(qū)中開辟的地址,這個操作我們前面的一級指針也可以完成,因此無需使用到二級指針,但是在外界傳參的時候我們還是選擇用二級指針接收以及指針的地址,因為函數(shù)的結(jié)構(gòu)已經(jīng)聲明了是無法改變的,不能因為第一次需要改變頭結(jié)點傳入二級指針,但是在后面要無需用到二級指針就突然將這個pphead變?yōu)橐患壷羔?#xff0c;這違背了編程的嚴(yán)謹(jǐn)性

接下去一樣通過函數(shù)棧幀來講解一下,加深印象,幫助理解

  • 可以看到,這里將SList拷貝給了pphead,然后pphead指向這個值為100的結(jié)點了,但是呢SList并沒有,這里的具體操作就是將SList這個一級指針的地址給到了二級指針pphead
  • pphead中存地是SList的地址,這里的【*pphead】解引用之后就是這個SList本身,然后主函數(shù)看到【SList = NULL】,所以在判斷【*pphead】的時候就想當(dāng)于在判斷【*SList】,這才會進(jìn)入if分支,通過讓【*pphead = newnode】也讓這個SList指向了100這個數(shù)據(jù)結(jié)點

  • 然后隨著PushBack函數(shù)的結(jié)束,函數(shù)所建立的棧幀也就被銷毀,pphead和pptail就都沒了,但此時這個SList卻通過二級指針傳參指向了尾插進(jìn)去的第一個結(jié)點,此時這個SList的頭部結(jié)構(gòu)才真正地被改變了,可以繼續(xù)尾插后面的結(jié)點

對于尾插法,你學(xué)【廢】會了嗎😝


2、尾刪【Circuitous】

有尾插,那一定也有尾刪,我們一起來探究一下

經(jīng)典錯誤案例分析

  • 對于尾刪我們一樣從一個經(jīng)典的錯誤案例開始說起
void SListPopBack(SLTNode* phead) {SLTNode* ptail = phead;while (ptail->next){ptail = ptail->next;}free(ptail);tail = NULL; }
  • 對于tail,當(dāng)其遍歷到最后一個結(jié)點,也就是next 為空的時候,跳出循環(huán),然后free釋放掉這個結(jié)點,然后又進(jìn)行了一步操作將這個tail的值置為空,這個意思就是想著說刪除了一個結(jié)點后尾結(jié)點繼續(xù)置為空
  • 有不少同學(xué)一開始都是這樣去是實現(xiàn)的,但這么去寫是會出現(xiàn)問題的,我們?nèi)eBug看一下

  • 通過DeBug我們可以看到,當(dāng)PopBack函數(shù)中將這個ptail置為NULL的時候,確實其內(nèi)存地址就變成了【0x00000000】,但是這也只是修改了這個局部變量ptail的值,與鏈表當(dāng)前一個結(jié)點的next域其實沒有任何關(guān)系,可以看到phead最后一個結(jié)點300的next于還是一個地址值,并沒有被置空,這其實就相當(dāng)于一個野指針一般,到后面萬一不小心去修改這個next值,就會造成很大的問題,有關(guān)野指針的問題,后面我會詳細(xì)敘述
  • 此時只是這個局部變量做了一個修改,并沒有改變這個結(jié)構(gòu)體,要改變結(jié)構(gòu)體就要使用到結(jié)構(gòu)體指針

修改方式一:保存ptail的上一個結(jié)點

  • 首先來看第一種修改方式,也就是將這個ptail向后遍歷的時候先做一個保存,放到一個結(jié)構(gòu)體指針prev中,在向后遍歷的時候若ptail遍歷到最后一個結(jié)點,直接free釋放ptail即可,然后讓prev->next = NULL,這個時候結(jié)構(gòu)體就發(fā)生了改變,這個next指針域也發(fā)生了真正的改變,不會像上面一樣變成一個野指針充滿【?dangerous?】
//way1 SLTNode* ptail = phead; SLTNode* prev = NULL; while (ptail->next != NULL) {prev = ptail;ptail = ptail->next; } free(ptail); prev->next = NULL;

修改方式二:ptail->next->next

  • 然后說說第二種修改方式,也就是不需要去再定義一個prev指針去保存,而是直接判斷【ptail->next->next】是否為空即可,此時這里的ptail便為尾結(jié)點的前一個結(jié)點,因此free(ptail->next)就是刪除尾結(jié)點,最后將這個結(jié)點置為空
//way2 SLTNode* ptail = phead; while (ptail->next->next != NULL) {ptail = ptail->next; } free(ptail->next); ptail->next = NULL;

特殊情況修正【單個結(jié)點、二級指針修改、斷言報錯】

  • 你以為用這樣就可以真正地實現(xiàn)尾刪了嗎,那還遠(yuǎn)遠(yuǎn)不夠,路還有很遠(yuǎn)🐎,繼續(xù)分析下去吧
  • 可以看到,在這里我執(zhí)行了三次PopBack,然后到最后一次的時候,發(fā)現(xiàn)ptail->next==NULL,但是ptail->next->next卻是一個越界的位置,這個時候其實就不對了,之前我們有說過,訪問越界是一個很大的問題

  • 所以,對于單個結(jié)點的尾刪,我們應(yīng)該進(jìn)行一個單獨的判斷。也就是當(dāng)前傳入進(jìn)來然后接收的這個phead所指向的next是否為空。若為空,則表示此單鏈表只有一個結(jié)點,直接free這個phead即可,然后將其置為NULL
void SListPopBack(SLTNode* phead) {if (phead->next == NULL){ //只有一個結(jié)點free(phead);phead = NULL;}else{SLTNode* ptail = phead;while (ptail->next->next != NULL){ptail = ptail->next;}free(ptail->next);ptail->next = NULL;} }
  • 那有同學(xué)說,這個時候應(yīng)該沒問題了吧,單個結(jié)點的情況都被我考慮到了,簡直天衣無縫😏
  • 但是。。。Exception它又來了

  • 不說了,沒有愛了??直接DeBug吧??
  • 那這里是又可以看到,我們在寫尾插的時候出現(xiàn)過的情況,就是函數(shù)內(nèi)部做了改變但是外界并不知曉,那這個時候該怎么辦呢?沒錯,就是它,👉二級指針👈

  • 那這下可好了,整個函數(shù)的結(jié)構(gòu)又要重新定義,這其實是正常的,調(diào)Bug就是不斷在試錯的過程,當(dāng)你找出錯來了,那就應(yīng)該及時更正,不要怕麻煩
  • 一樣,就像下面這么改,對于只有單個結(jié)點需要單獨處理時使用*pphead去獲取一級指針進(jìn)行操作~
void SListPopBack(SLTNode** phead) {if ((*phead)->next == NULL){ //若只有一個結(jié)點,直接將其釋放,傳入二級指針便改變了鏈表的頭結(jié)點free(*phead);*phead = NULL;}else{SLTNode* ptail = *phead;while (ptail->next->next != NULL){ptail = ptail->next;}free(ptail->next);ptail->next = NULL;} }
  • 然后我們再來看一下運行結(jié)果,可以看到,鏈表終于被清干凈了


  • 真的是天衣無縫、百無一失了嗎?我再刪一次你看看😱

  • 可以看到,此時的鏈表已經(jīng)為空,但是我又執(zhí)行了一次PopBack操作,那有同學(xué)說,那你這不是手欠嗎,人家都被刪空了你還要再刪一次,成心跟人過不去是吧😠
  • 記住一點,你永遠(yuǎn)要考慮要一些隨性操作的用戶,指不定那天進(jìn)行了一些你開發(fā)時想都想不到的操作🐭

  • 這其實就是什么問題?沒錯,就是訪問越界的問題,當(dāng)你將鏈表已經(jīng)刪空的時候,再去對鏈表進(jìn)行一個刪除,此時訪問的就是一個隨機(jī)的位置,超出了你所能訪問的界限,編譯器也就很好地為你【檢查出了錯誤】
  • 那此時我們應(yīng)該怎么辦呢?沒錯,就是在PopBack函數(shù)進(jìn)來的一開始,就進(jìn)行一個判斷,看看這個指針?biāo)赶虻念^是否為空,若是為空,則執(zhí)行相應(yīng)的報錯
  • 在這里我們選擇直接使用暴力的方式,也就是斷言【assert】,不要溫柔的if判斷,直接報出來哪里有問題,然后打一頓再說💪
void SListPopBack(SLTNode** phead) {assert(*phead);if ((*phead)->next == NULL){ //若只有一個結(jié)點,直接將其釋放,傳入二級指針便改變了鏈表的頭結(jié)點free(*phead);*phead = NULL;}else{SLTNode* ptail = *phead;while (ptail->next->next != NULL){ptail = ptail->next;}free(ptail->next);ptail->next = NULL;}

以上就是尾刪法的最終版本,你又學(xué)【廢】了嗎😝


說完尾插和尾刪,還有頭插和頭刪,但是不要驚慌,對于頭插和頭刪,沒有你想象得那么復(fù)雜😵

3、頭插【Easy】

  • 對于頭插其實并不復(fù)雜,也就是創(chuàng)建出一個新的結(jié)點newnode,然后讓這個結(jié)點的next域存放首個結(jié)點的地址,還是一樣,對于頭插和頭刪,都是要使用到二級指針的,否則內(nèi)部的改動是無法帶動外部的變化
  • 要將這個二級指針化為一級指針我們說過很多遍,一次*解引用即可。鏈接上后將這個新的頭所存在的地址給到指向頭結(jié)點的指針即可

void SListPushFront(SLTNode** pphead, SLTDataType x) {SLTNode* newnode = BuySLTNode(x);newnode->next = (*pphead); //二級指針解引,變?yōu)橐患壷羔?/span>*pphead = newnode; //再讓newnode變?yōu)樾碌念^ }
  • 怎么樣,簡單吧,很快就說完了,一方面是因為我們前面鋪墊得很多,你所掌握的東西我已經(jīng)不需要說了,另一方面在對于單鏈表而言,它的頭插和頭刪確實比尾插和尾刪來得高效

4、頭刪【Easy】

  • 說完頭插,馬上趁熱打鐵來說說頭刪
  • 還是一樣,并不復(fù)雜。因為刪除這個頭,那當(dāng)其刪除之后,它的后一個結(jié)點也就成為了新的頭,這個時候就需要做一個更新,但這個前提是你能訪問到后面這個結(jié)點,所以我們要事先去保存當(dāng)前頭結(jié)點的后一個結(jié)點,然后將頭結(jié)點free釋放,最后更新讓頭結(jié)點指針重新指向下一個新的結(jié)點即可


void SListPopFront(SLTNode** pphead) {assert(*pphead); //刪除都先斷言一下,看看傳進(jìn)來的鏈表是否為空SLTNode* next = (*pphead)->next; //先保存當(dāng)前首結(jié)點的下一個結(jié)點free(*pphead);(*pphead) = next; }

5、查找

  • 看完了尾插、尾刪、頭插、頭刪。接下來我們要學(xué)習(xí)的是去鏈表中查找指定元素,先來看看接口定義
SLTNode* SListFind(SLTNode* phead, SLTDataType x);
  • 可以看到,形參接收的是頭結(jié)點指針,以及需要查找的值,返回值類型是一個結(jié)構(gòu)體指針,也就是說返回的是一個指向待查結(jié)點的結(jié)構(gòu)體指針,并不是一個下標(biāo),一個位置,那函數(shù)內(nèi)部我們該如何去寫呢?
  • 很簡單,只需要一個cur指針先獲取頭結(jié)點的指向,然后一個個向后查詢即可,若是發(fā)現(xiàn)其指向的data值相同,便返回當(dāng)前的cur指針
SLTNode* cur = phead; //while (cur != NULL) while (cur) {if (cur->data == x)return cur;cur = cur->next; } return NULL; //返回的是指向這個待查結(jié)點的指針,并不是位置
  • 我們來測試一下看看
SLTNode* SList = NULL; SListPushBack(&SList, 1); SListPushBack(&SList, 2); SListPushBack(&SList, 3); SListPushBack(&SList, 4); SListPushBack(&SList, 5); PrintList(SList);SLTNode* pos = SListFind(SList, 3); if (pos != NULL) {printf("找到了\n");printf("pos = %d\n", pos->data); } else {printf("沒找到\n"); }

  • 可以看到,確實是可以找到,我將這個結(jié)點的data值打印了出來

那有同學(xué)問,找到返回了這個值又能怎樣呢,可以拿來做什么?那我告訴你這個用處可大了,后面我們將在找到的這個pos所指的結(jié)點之前、之后進(jìn)行插入和刪除相應(yīng)的結(jié)點,都是要以這個Find接口作為前提

6、在pos位置之后插入結(jié)點

  • 接下來我們就來看一看如何在找到的pos位置之后插入一個結(jié)點呢

  • 可以看到,我們最后要達(dá)到的是這種效果,就是pos的next要指向這個newnode,然后newnode的next要指向pos->next,這時候有些同學(xué)就會這么去寫。先讓這個pos的next指向newnode,然后再讓newnode的next指向pos的next
  • 這個邏輯其實就有問題,當(dāng)pos的next所指位置變化之后也就找不到4這個結(jié)點了,執(zhí)行完第一條語句后pos的next就變成了newnode,這個時候再讓newnode指向pos的next,也就是讓newnode指向它自己,這也就不對了
//pos的下一個位置就沒了,相當(dāng)于是newnode自己指向自己 pos->next = newnode; newnode->next = pos->next;
  • 所以應(yīng)該把這兩條語句做一個交換。先讓newode的next指向pos的next,也就是4,然后再讓pos指向這個newnode,這個時候結(jié)點之間的鏈接就沒問題了😯
newnode->next = pos->next; pos->next = newnode;
  • 通過這段代碼,我們插入一個值試試看。從打印結(jié)果看來,確實在3后面插入了一個9

警惕傳入空指針【?細(xì)致講解斷言assert】

  • 還是一樣,繼續(xù)思考有沒有可能出現(xiàn)特殊情況,我們來看看這種
  • 可以看到,鏈表中的結(jié)點值只有1~5但是卻需要找一個88,很明顯是找不到的,此時便會return NULL,那么外界的pos接受到的值就是一個空值,也就說這是一個空指針,所以當(dāng)你傳一個空指針進(jìn)去,你讓函數(shù)內(nèi)部怎么實現(xiàn)一個插入呢
SLTNode* pos = SListFind(SList, 88); SListInsertAfter(pos, 9); PrintList(SList);
  • 此時可以看到,程序發(fā)生了奔潰/(ㄒoㄒ)/~~

  • 看到這個地方,我相信你的第一反應(yīng)就是在函數(shù)一開始的加一個斷言,判斷這個pos是否為空
  • 可能有些同學(xué)不了解里面的傳參機(jī)制以及判斷機(jī)制,我這里講一下:對于assert斷言來說,就是還函數(shù)還沒有執(zhí)行的時候去做的一件事,而不是應(yīng)該把它放在函數(shù)體的中間或者結(jié)尾,這點首先要明確;其次assert斷言的內(nèi)部參數(shù)你需要傳入的是你需要檢查的傳入進(jìn)來的某個參數(shù)變量,一般是去判斷是否為空或者是否小于0。所以對于參數(shù),你應(yīng)該寫入的是會報出錯誤的對立面,舉個例子,當(dāng)你想要檢查a是否大于0,a小于0就會報錯,因此應(yīng)該寫assert(a > 0)。若是去判斷一個指針是否為空,就要這樣寫:assert(p != NULL),或者直接簡寫成assert( p ),就想我們的while循環(huán)去判空是一個道理;知道了傳參邏輯,最后說說assert的判斷機(jī)制,就是當(dāng)你所寫的表達(dá)式不成立時,也就是當(dāng)【p == NULL】時,就會出現(xiàn)警告,報出錯誤。在計算機(jī)中【0是假,非0才是真】,當(dāng)【p = NULL】時,這個表達(dá)式就變?yōu)榱思?#xff0c;非0一般指1,就是p != NULL,表明傳進(jìn)來的指針p不為空,那也就是不會滿足條件
  • 我們通過CPlusPlus來看看,明確說到當(dāng)表達(dá)式的值為0的時候,就會向標(biāo)準(zhǔn)的錯誤設(shè)備寫入一條消息終止調(diào)用,也就是斷言assert后面的語句均不會執(zhí)行

  • 所以應(yīng)該在InsertAfter函數(shù)的開頭加上這一句話
//0是假,非0才是真 assert(pos != NULL); //若不為空,則不會執(zhí)行;若為空,則報出警告 //assert(pos);
  • 此時可以看到,加上這句話后斷言就出現(xiàn)了,直接給你報出了那個cpp文件的哪一行出了問題,也就是我們剛才寫斷言的地方,這個時候你立馬可以進(jìn)行精確定位然后排錯,這個時候也就提高了程序的可維護(hù)性,所以作為我們程序員來說,學(xué)會使用斷言是很重要的,但是斷言并不是什么地方都可以隨便加的,根據(jù)需求來加,也就是【因地制宜】,不然會出現(xiàn)麻煩,結(jié)尾總結(jié)的時候會說到📖

【生活小案例3——請人吃飯要帶錢💴】

  • 通過傳入空指針去插入一個結(jié)點可以看到是一個很荒謬的事情,我們聯(lián)想一個生活中的小案例來理解一下,順便輕松一刻,你傳入一個空指針和一個待插入的結(jié)點值,其實就相當(dāng)于你帶你說今天請你朋友去外面吃飯,但是吃飯之后一看錢包是空的,于是這個時候就只能讓你朋友付錢了【假設(shè)不支持手機(jī)支付】,那你說這個事情是不是很荒謬,assert斷言其實就是在出門之前檢查一下你有沒有帶錢,如果沒有帶那就會報出警告提醒你要帶錢出門
  • 所以在函數(shù)進(jìn)行傳遞指針的時候一定要檢查傳遞的是不是空指針,就想出門檢查自己有沒有帶錢是一個道理

7、在pos位置之前插入結(jié)點

  • 說完了在這個pos位置之后插入結(jié)點,那有后一定有前,現(xiàn)在我們來談一談如何在獲取到的pos位置前插入一個結(jié)點。對于這個,說在前面,會出現(xiàn)兩種情況:一種是當(dāng)前找到的pos在鏈表中間的某個地方,還有一種比較特殊,就是這個pos剛好是頭結(jié)點,這個時候進(jìn)行的其實就是我們上面說過的頭插法,那既然是頭插法,就需要去改變這個鏈表的頭,所以又需要使用到二級指針
void SListInsertBefore(SLTNode** pphead, SLTNode* pos, SLTDataType x) {if (*pphead == pos) {//若pos位置就為原先的頭結(jié)點,則使用頭插法進(jìn)行插入SListPushFront(pphead,x);}else {SLTNode* cur = *pphead;while (cur->next != pos){cur = cur->next;}SLTNode* newnode = BuySLTNode(x);//此處無需考慮前后錯亂問題,直接鏈接即可cur->next = newnode;newnode->next = pos;} }
  • 直接給出代碼做講解。一樣的老套路,通過*pphead進(jìn)行解引用,獲取到外界SList這個頭結(jié)點指針,然后去進(jìn)行一個判斷即可,若這個 *phead真的和pos相同,直接調(diào)用一下我們上面寫過的頭插法即可,實現(xiàn)了功能的復(fù)用,具體圖示如下👇

  • 然后再來說一下普通情況,也就是在鏈表其中的某一個位置前插入,所以我們要獲取pos指針?biāo)赶虻那耙粋€位置,開頭說到過,雖然單鏈表對于插入和刪除很方便,但是訪問結(jié)點并不方便,需要從頭結(jié)點開始訪問,于是還是一樣的套路,定義一個cur指針首先獲取到頭結(jié)點指針的值,也就是把二級指針pphead解引用一下,然后一直去遍歷即可,直到這個【cur->next = pos】為止,停下來,此時就可以做一個鏈接了,具體圖示如下👇
  • 可以看到,此時無需像在后面插入結(jié)點一般去考慮這個先后的順序關(guān)系,只需要將【cur】【newnode】【pos】這三個指針做一個鏈接即可

  • 最后我們來通過測試驗證一下結(jié)果
  • 這是普通情況

  • 來看特殊情況


看完了如何插入結(jié)點,接下去我們來說說如何在查找到的pos位置前后刪除結(jié)點

8、刪除pos位置之后的結(jié)點

  • 首先來說一說如何刪除pos位置之后的結(jié)點
  • 首先來看一下函數(shù)體聲明,很明顯,只需要傳入一個pos指針即可,其余不需要
void SListEraseAfter(SLTNode* pos)
  • 然后我們來考慮函數(shù)體內(nèi)部,首先要做的事情相信你已經(jīng)很敏感了,對于刪除我們都要assert一下這個傳入的指針是否為空,若為空則不能對其進(jìn)行操作。然后需要考慮的就是特殊情況,有什么特殊情況呢?就是下面這種pos為最后一個尾結(jié)點時,后面沒有結(jié)點可刪,此時直直接return返回即可,當(dāng)然你也可以用assert斷言

  • 然后就是這種正常的情況,我們需要修改pos所在結(jié)點的指針域,因為刪除了后一個結(jié)點,所以要將其指針域改為下一個結(jié)點的再下一個結(jié)點,于是有同學(xué)就會這么寫。這里寫其實是有問題的,從內(nèi)存的角度來說,因為pos的next已經(jīng)改變了,此時【pos->next】這塊地址已經(jīng)訪問不到了,再去free的話也是徒勞
pos->next = pos->next->next; free(pos->next);
  • 因為我們需要將【pos->next】做一個臨時保存,這樣當(dāng)pos的next指針域改變時,也可以訪問到這個被刪除的結(jié)點

  • 具體代碼如下
void SListEraseAfter(SLTNode* pos) {assert(pos);SLTNode* nextNode = pos->next;if (nextNode == NULL){return; //考慮到所查找到的結(jié)點為最后一個結(jié)點,后面無結(jié)點可刪}else {pos->next = nextNode->next;free(nextNode);}
  • 那這個時候有同學(xué)又來抬杠說,再定義一個看著冗雜,為啥不先把這個結(jié)點釋放,然后再修改指針域呢?
  • 大家覺得這樣可以嗎?
free(pos->next); pos->next = pos->next->next;
  • 其實這是一種非常典型的錯誤,很多同學(xué)都容易犯,當(dāng)你將這個結(jié)點free掉之后,那也就是說其data域和next都沒了,但是待刪結(jié)點3的next域存放有結(jié)點4的地址,你講它提前釋放了,那pos怎么找得到呢,此時【pos->next】就變成了一種我們都聽說過的東西,叫做【野指針】,可能有小伙伴沒聽說過,也沒關(guān)系,我們可以來了解一下

野指針的危害【生活小案例4——酒店房門的鑰匙🔑】

  • 就我們理解而言,指針都是指向一個地址,野指針也不例外,它指向一個地址,但是呢,這塊地址不是確定的,而是隨機(jī)的。
  • 這一塊我不是非常了解,大家可以看看這篇博客——》野指針的產(chǎn)生及其危害

通過閱讀這篇文章,我也了解到了一些有關(guān)野指針的知識,但是這么理解起來比較晦澀難懂,因為還是按照我們的慣例,通過生活的一個小案例來幫助大家理解

  • 首先來說一說釋放結(jié)點的含義:對于結(jié)點的釋放呢,并不是把此結(jié)點存放的地址給銷毀了,而是此結(jié)點所存放的地址的使用權(quán)不屬于你了,還給了操作系統(tǒng)。對于申請內(nèi)存就像去酒店開房間,這個房間的使用權(quán)就屬于你了,不會有人突然闖進(jìn)來,釋放了就相當(dāng)于是退房了,這個房間的使用權(quán)就不屬于你了,但是這個房間還在【這一點很重要,這個房間還在!!】
  • 剛才說到酒店開房,我們具體來說說:你在酒店🏨開了一個房間,住了一晚后把這個房間退了,但是在走之前打電話找了一個鎖匠根據(jù)這個房間的所配了一把鑰匙。野指針訪問隨機(jī)內(nèi)存就好比你后一個晚上沒有登記入住但是卻通過這把自己裝配的鑰匙進(jìn)入了這個房間,又在里面住了一個晚上然后這個晚上剛好沒什么客人,保潔阿姨也請假了,所以你又白嫖了一個晚上。于是你打算明天再來住一次,可是這一次,卻有很大的禍患,晚上來了一個旅行團(tuán),于是很多房間都要重新打掃,然后就發(fā)現(xiàn)你還住在這里,就報警把你抓了起來👮
  • 這把鑰匙其實就相當(dāng)于是野指針。野指針真正的危害在于【這塊內(nèi)存已經(jīng)釋放了,是一個隨機(jī)值,但還有一個指針指向這塊地址,但是這個地址是不被保護(hù)的,隨時都有可能出問題】
  • 所以對于野指針的訪問不一定會報錯,取決你有沒有被編譯器查到💻

通過這么一個案例,大家對野指針這一塊應(yīng)該有所了解了,所以不要輕易將指針亂指,可能那塊地址就是隨機(jī)的


  • 看了野指針的危害,我們繼續(xù)回到代碼中來DeBug看看,使用野指針會出現(xiàn)什么情況
free(pos->next); pos->next = pos->next->next;
  • 從圖中可以看出,一開始進(jìn)去的時候,pos->next也就是我們定義的nextNode,存有4的地址,但是當(dāng)我們先去free之后,這個地址就不見了,而且數(shù)據(jù)值也變成了一個隨機(jī)值,所以這個時候再去訪問pos->next就是一個【野指針】了


  • 但是這個時候編譯器卻不會報錯,正常運行下去了,此時我們來看看外界的SList
  • 可以看出,確實出問題了,我們需要刪除的是pos所指向的next,也就是3這個位置,但是當(dāng)先free之后,此時4也沒有了,找不到了,2的next指向的是一個隨機(jī)的地址,那編譯器對于這種問題不會報錯嗎?當(dāng)然會,但不會是在這里,而是在Print中

  • 因為打印的時候需要隨著next指針?biāo)娣诺牡刂芬灰辉L問,因此當(dāng)訪問到2的next時,便出現(xiàn)了訪問異常,因為它訪問的是一塊不確實的地址,是沒有被分配的,里面沒有任何東西,因此這時編譯器就會報出異常

所以大家在進(jìn)行指針操作的時候一定要小心,可以一疏忽你的指針就變成了野指針🗡

9、刪除pos位置之前的結(jié)點

  • 說完了pos位置之后的結(jié)點刪除操作,那之前的一定也要說,和這個和插入一樣,會有多種情況,可能會改變頭結(jié)點,因此需要使用到二級指針
void SListEraseBefore(SLTNode** pphead, SLTNode* pos)

第一種:pos就位于頭結(jié)點位置

  • 這種情況的話是無法刪除的,因為頭結(jié)點前面為空,所以直接返回即可,當(dāng)然你也可以assert
//當(dāng)pos就為頭結(jié)點時 if ((*pphead) == pos) {return; }

第二種:pos位于頭結(jié)點的后一個位置,需要刪除的便為頭結(jié)點

  • 這個的話就是我們前面講到過的頭刪,直接調(diào)用即可

else if ((*pphead)->next == pos) {SListPopFront(pphead); //頭刪 }

第三種:正常情況,但是比較繁瑣

  • 對于正常情況,其實是比較麻煩的,我們來看看

  • 對于這種情況,因為我們是要去刪除pos結(jié)點的前一個結(jié)點,但是我們知道,要刪除一個結(jié)點,就要找到它的前一個結(jié)點,因此這個時候我們需要定義一個結(jié)構(gòu)體指針cur,剛開始指針【*pphead】,在不斷往后遍歷的時候當(dāng)【cur->next->next == pos】時,定義一個指針指向當(dāng)前cur的next,進(jìn)行一個保存,接著執(zhí)行【cur->next = delnode->next】,便可以進(jìn)行一個刪除
  • 具體代碼如下
void SListEraseBefore(SLTNode** pphead, SLTNode* pos) {assert(pos); //刪除結(jié)點要斷言assert(*pphead); //當(dāng)pos就為頭結(jié)點時if ((*pphead) == pos) {return;} //當(dāng)刪除的結(jié)點為頭結(jié)點時else if ((*pphead)->next == pos) {SListPopFront(pphead); //頭刪}else {SLTNode* cur = *pphead;while (cur->next->next != pos)cur = cur->next;SLTNode* delnode = cur->next;cur->next = delnode->next;free(delnode);} }
  • 我們來測試一下看看



10、釋放鏈表

  • 最后的壓軸💃當(dāng)然是給到Destroy,既然Create了,那一定要Destroy,有始有終,才是最好
  • 首先說一下整體思路。對于單鏈表來說,它和順序表并不一樣,因為對于順序表而言,是一塊連續(xù)的存儲空間,申請的時候是一整塊一起申請,釋放的時候自然也是一整塊一起釋放,因此直接free即可。但是對于鏈表不同,鏈表的每一個結(jié)點在堆內(nèi)存中的空間是隨機(jī)申請的。因此存儲是不連續(xù)的,那對于釋放來說,就需要從頭結(jié)點開始,一一釋放下去
  • 首先還是一樣,保留好頭結(jié)點,拿一個指針代替,接著在釋放頭結(jié)點的時候還要先行保存其下一個結(jié)點,然后free掉當(dāng)前的cur結(jié)點,讓cur結(jié)點指向下一個結(jié)點,繼續(xù)進(jìn)行一個釋放

  • 看一下代碼
void SLIstDestroy(SLTNode** pphead) {SLTNode* cur = *pphead;while (cur){SLTNode* nextNode = cur->next;free(cur);cur = nextNode;} }
  • 你覺得這樣可以了嗎?那有同學(xué)可以說我這么問肯定是不可以,那你知道缺了什么嗎,我們將一個單鏈表Destory一下試試,然后將其打印出來再看看

  • 是的,可以看到又是我們所熟悉的野指針,為什么呢?因為你將鏈表的頭結(jié)點釋放了,那這就是一塊隨機(jī)的地址,上面說到過,訪問一塊隨機(jī)的地址,也就形成了【野指針】

【生活小案例5——利劍不鋒利🗡】

  • 上面又說到了這個野指針的問題,我們再來談一談,對于野指針,也是它就像是一把鋒利的劍一樣,非常危險,但是呢,它又不是隨時都會有危險,因為當(dāng)這把劍放在劍鞘中時,其實是非常安全的,并不是傷害到你,但是當(dāng)你將它把出來的時候,那這個時候你就要小心使用了,一不留神可能就會傷到自己。
  • 對于野指針也是一樣,有的時候你知道這個指針可能會是野指針,但是你不去使用它訪問數(shù)據(jù),那其實是很安全的,不會有問題,但是當(dāng)你使用到了這個野指針去訪問的時候,其實就會非常危險了。所以在這里還是和大家說一句:謹(jǐn)慎使用指針

好,我們回歸正題,既然這樣會造成野指針,那應(yīng)該怎么修改呢,那就是將和這個頭結(jié)點指針置為NULL即可,這個時候再去打印的時候這個鏈表就是空的,也就不會出錯了


四、整體代碼展示【需要自取】

SList.h

#pragma once #include <stdio.h> #include <stdlib.h> #include <assert.h>typedef int SLTDataType; typedef struct SListNode { //結(jié)構(gòu)體大小:8BSLTDataType data;struct SListNode* next;//SLT* next; 不可以這樣定義,因為還沒有到聲明 }SLTNode;SLTNode* BuySLTNode(SLTDataType x); SLTNode* SListCreate(int n); void PrintList(SLTNode* phead);void SListPushBack(SLTNode** phead, SLTDataType x); void SListPopBack(SLTNode** phead); void SListPushFront(SLTNode** pphead, SLTDataType x); void SListPopFront(SLTNode** pphead);SLTNode* SListFind(SLTNode* phead, SLTDataType x); void SListInsertAfter(SLTNode* pos, SLTDataType x); void SListInsertBefore(SLTNode** pphead, SLTNode* pos, SLTDataType x); void SListEraseAfter(SLTNode* pos); void SListEraseBefore(SLTNode** pphead, SLTNode* pos); void SLIstDestroy(SLTNode** pphead);

SList.cpp

#define _CRT_SECURE_NO_WARNINGS 1 #include "SList.h" //----------------- /*動態(tài)開辟結(jié)點*/ SLTNode* BuySLTNode(SLTDataType x) {//動態(tài)開辟SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("malloc fail\n");exit(-1);}newnode->data = x;newnode->next = NULL; } //----------------- /*建立鏈表*/ SLTNode* SListCreate(int n) {SLTNode* phead = NULL, * ptail = NULL;for (int i = 0; i < n; ++i){SLTNode* newnode = BuySLTNode(i);if (phead == NULL)phead = ptail = newnode;else{ptail->next = newnode;ptail = newnode;}}return phead; } //----------------- /*打印鏈表*/ void PrintList(SLTNode* phead) {//無需斷言,鏈表為空,可以打印SLTNode* cur = phead; //盡量不用頭指針,定義變量存放【4 byte】while (cur != NULL){printf("%d->", cur->data);//printf("[%d|%p]->", cur->data,cur->next);cur = cur->next;}printf("NULL\n"); } //----------------- /*尾插*/ void SListPushBack(SLTNode** pphead, SLTDataType x) {//無需斷言,鏈表為空,可以尾插SLTNode* newnode = BuySLTNode(x);if (*pphead == NULL){*pphead = newnode;//通過二級指針的解引用改變頭結(jié)點【從NULL->newnode】}else{SLTNode* pptail = *pphead;while (pptail->next){pptail = pptail->next;//無需再使用二級指針,無需改變頭結(jié)點,只需要做一個鏈接//改變結(jié)構(gòu)體的指向,使用結(jié)構(gòu)體指針}pptail->next = newnode;} } //----------------- /*尾刪*/ void SListPopBack(SLTNode** phead) {assert(*phead); //必須斷言,鏈表為空,不可尾刪if ((*phead)->next == NULL){ //若只有一個結(jié)點,直接將其釋放,傳入二級指針便改變了鏈表的頭結(jié)點free(*phead);*phead = NULL;}else{SLTNode* ptail = *phead;while (ptail->next->next != NULL){ptail = ptail->next;}free(ptail->next);ptail->next = NULL;} } //----------------- //頭插 void SListPushFront(SLTNode** pphead, SLTDataType x) {//無需斷言,鏈表為空,可以頭插SLTNode* newnode = BuySLTNode(x);newnode->next = (*pphead); //二級指針解引,變?yōu)橐患壷羔?/span>*pphead = newnode; //再讓newnode變?yōu)樾碌念^ }//----------------- //頭刪 void SListPopFront(SLTNode** pphead) { //必須斷言,鏈表為空,不可頭刪assert(*pphead); //刪除都先斷言一下,看看傳進(jìn)來的鏈表是否為空SLTNode* next = (*pphead)->next; //先保存當(dāng)前首結(jié)點的下一個結(jié)點free(*pphead);(*pphead) = next; } //----------------- //查找 SLTNode* SListFind(SLTNode* phead, SLTDataType x) {SLTNode* cur = phead;//while (cur != NULL)while (cur){if (cur->data == x)return cur;cur = cur->next;}return NULL;//返回的是指向這個待查結(jié)點的指針,并不是位置 } //----------------- //在pos位置之后插入結(jié)點 void SListInsertAfter(SLTNode* pos, SLTDataType x) {//0是假,非0才是真assert(pos != NULL); //若不為空,則不會執(zhí)行;若為空,則報出警告SLTNode* newnode = BuySLTNode(x);//pos->next = newnode;//newnode->next = pos->next;//pos的下一個位置就沒了,相當(dāng)于是newnode自己指向自己newnode->next = pos->next;pos->next = newnode; } //----------------- //在pos位置之前插入結(jié)點 void SListInsertBefore(SLTNode** pphead, SLTNode* pos, SLTDataType x) {if (*pphead == pos) {//若pos位置就為原先的頭結(jié)點,則使用頭插法進(jìn)行插入SListPushFront(pphead,x);}else {SLTNode* cur = *pphead;while (cur->next != pos){cur = cur->next;}SLTNode* newnode = BuySLTNode(x);//此處無需考慮前后錯亂問題,直接鏈接即可cur->next = newnode;newnode->next = pos;} } //----------------- //刪除pos位置之后的結(jié)點 void SListEraseAfter(SLTNode* pos) {assert(pos);SLTNode* nextNode = pos->next;if (nextNode == NULL){return; //考慮到所查找到的結(jié)點為最后一個結(jié)點,后面無結(jié)點可刪}else {//free(pos->next); //會產(chǎn)生野指針//pos->next = pos->next->next;pos->next = nextNode->next;free(nextNode);} //----------------- //刪除pos位置之前的結(jié)點 void SListEraseBefore(SLTNode** pphead, SLTNode* pos) {assert(pos); //刪除結(jié)點要斷言assert(*pphead); //當(dāng)pos就為頭結(jié)點時if ((*pphead) == pos) {return;} //當(dāng)刪除的結(jié)點為頭結(jié)點時else if ((*pphead)->next == pos) {SListPopFront(pphead); //頭刪}else {SLTNode* cur = *pphead;while (cur->next->next != pos)cur = cur->next;SLTNode* delnode = cur->next;cur->next = delnode->next;free(delnode);} } //----------------- //釋放鏈表 void SLIstDestroy(SLTNode** pphead) {SLTNode* cur = *pphead;while (cur){SLTNode* nextNode = cur->next;free(cur);cur = nextNode;}*pphead = NULL; }

test.cpp

#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <malloc.h> #include "SList.h"/* 順序表缺陷 * 1.空間不夠,需要擴(kuò)容。擴(kuò)容(尤其是異地擴(kuò)容)是有一定代價的。其次還可能存在一定的空間浪費 * --》擴(kuò)容都是擴(kuò)2倍,擴(kuò)得多了,一些不用空間的就會浪費 * --》擴(kuò)得少了,插入一些數(shù)空間又不夠了,又需要頻繁的擴(kuò)容 * * 【吃米飯】一碗不夠,吃兩碗 * 吃一碗零20粒,頻繁去鍋里舀飯 * * 2.頭部或者中部插入刪除,需要挪動數(shù)據(jù),效率低下 *//* 優(yōu)化方案 * 1.按需申請釋放【要存儲一個數(shù)據(jù)就開一塊空間(結(jié)點)】 * 2.不要挪動數(shù)據(jù)【指針可以存放下一塊空間的地址】 *//* * 順序表支持隨機(jī)訪問,可以根據(jù)下標(biāo)快速訪問到某個元素 * 鏈表不支持隨機(jī)訪問,只能通過頭結(jié)點的next指針域一個個訪問下去,最壞會到達(dá)O(N) * 假設(shè)順序表是貨車,鏈表是公交車,都是不可替代的 */ void TestSList1() { SLTNode* n1 = (SLTNode*)malloc(sizeof(SLTNode));SLTNode* n2 = (SLTNode*)malloc(sizeof(SLTNode));n1->next = n2;SListNode n3, n4;n3.next = &n4;}void TestSList2() {/**/SLTNode* n1 = BuySLTNode(1);SLTNode* n2 = BuySLTNode(2);SLTNode* n3 = BuySLTNode(3);SLTNode* n4 = BuySLTNode(4);n1->next = n2;n2->next = n3;n3->next = n4;n4->next = NULL;SLTNode* SList = SListCreate(5);PrintList(SList); }void Swap1(int* p1, int* p2) {int tmp = *p1;*p1 = *p2;*p2 = tmp; }void Swap2(int** pp1, int** pp2) {int* tmp = *pp1;*pp1 = *pp2;*pp2 = tmp; } void test1() {int a = 2, b = 5;//printf("a = %d, b = %d\n", a, b);//Swap1(&a, &b);//printf("a = %d, b = %d\n", a, b);int* p1 = &a, * p2 = &b;printf("*p1 = %d, *p2 = %d\n", *p1, *p2);Swap2(&p1, &p2);printf("*p1 = %d, *p2 = %d\n", *p1, *p2);printf("a = %d, b = %d\n", a, b); }//尾插 void TestSList3() {//SLTNode* SList = SListCreate(10);//PrintList(SList);//SListPushBack(SList, 100);//SListPushBack(SList, 200);//SListPushBack(SList, 300);SLTNode* SList = NULL;SListPushBack(&SList, 100);SListPushBack(&SList, 200);SListPushBack(&SList, 300);PrintList(SList); }//尾刪 void TestSList4() {SLTNode* SList = NULL;SListPushBack(&SList, 100);SListPushBack(&SList, 200);SListPushBack(&SList, 300);PrintList(SList);SListPopBack(&SList);PrintList(SList);SListPopBack(&SList);PrintList(SList);SListPopBack(&SList);PrintList(SList);//再多刪一次SListPopBack(&SList); //訪問越界PrintList(SList); }//頭插 — 頭刪 //void TestSList5() //{ // SLTNode* SList = NULL; // printf("尾插:"); // SListPushBack(&SList, 100); // SListPushBack(&SList, 200); // SListPushBack(&SList, 300); // PrintList(SList); // // SLTNode* SList2 = NULL; // printf("頭插:"); // SListPushFront(&SList2, 100); // SListPushFront(&SList2, 200); // SListPushFront(&SList2, 300); // SListPushFront(&SList2, 400); // PrintList(SList2); // // printf("頭刪:\n"); // SListPopFront(&SList2); // PrintList(SList2); // SListPopFront(&SList2); // PrintList(SList2); // SListPopFront(&SList2); // PrintList(SList2); // SListPopFront(&SList2); // PrintList(SList2); //}//查找與插入 void TestSList6() {SLTNode* SList = NULL;SListPushBack(&SList, 1);SListPushBack(&SList, 2);SListPushBack(&SList, 3);SListPushBack(&SList, 4);SListPushBack(&SList, 5);PrintList(SList);//SLTNode* pos = SListFind(SList, 3);//if (pos != NULL) {// printf("找到了\n");// printf("pos = %d\n", pos->data);// SListInsertAfter(pos, 9);// PrintList(SList);//}//else {// printf("沒找到\n");//}//SLTNode* pos = SListFind(SList, 88);//SListInsertAfter(pos, 9);//PrintList(SList);//SLTNode* pos = SListFind(SList, 3);//SListInsertAfter(pos, 9);//PrintList(SList);//SListInsertBefore(&SList, pos, 11);//PrintList(SList);SLTNode* pos = SListFind(SList, 1);SListInsertBefore(&SList, pos, 8);PrintList(SList); } //刪除之后的結(jié)點 void TestSList7() {SLTNode* SList = NULL;SListPushBack(&SList, 1);SListPushBack(&SList, 2);SListPushBack(&SList, 3);SListPushBack(&SList, 4);PrintList(SList);SLTNode* pos = SListFind(SList, 2);SListEraseAfter(pos);PrintList(SList); } void TestSList8() {SLTNode* SList = NULL;SListPushBack(&SList, 1);SListPushBack(&SList, 2);SListPushBack(&SList, 3);SListPushBack(&SList, 4);PrintList(SList);//SLTNode* pos = SListFind(SList, 4);SLTNode* pos = SListFind(SList, 2);//SLTNode* pos = SListFind(SList, 1);SListEraseBefore(&SList, pos);PrintList(SList);SLIstDestroy(&SList);PrintList(SList);} void test() {int a = 'o';printf("%d\n", a); } int main(void) {//TestSList2();//test1();//TestSList3();//TestSList4();//TestSList5();//TestSList6();//TestSList7();TestSList8();//test();return 0; }

五、有關(guān)二級指針和斷言的小結(jié)【?謹(jǐn)記?】

  • 看完了上述有關(guān)單鏈表的所有操作,從這些代碼中我們可以看到對于二級指針和斷言的使用比較頻繁,很多接口算法中都用到了這兩個東西,但是對于二級指針和斷言,并不是什么地方都要使用的。
  • 仔細(xì)地分析一下就可以知道,對于頭插、尾插、頭刪、尾刪這些操作,以及在pos結(jié)點之前插入和刪除結(jié)點、銷毀結(jié)點,這些接口均需要使用到二級指針來接受鏈表的頭指針,這是為什么呢?不知道大家有沒有想過,那我在各個算法的講解過程中其實都是從一級指針轉(zhuǎn)換到二級指針,原因就是對于函數(shù)內(nèi)部頭結(jié)點的修改不會影響外部頭結(jié)點指針的修改,而且我在二級指針引入那一塊也說到了要改變【int】,就要使用【int*】;要改變【int*】,就要使用【int**】,也就是說我們要改變一級頭結(jié)點指針就要使用二級指針去修改,對于上面這些接口操作,均需要修改頭結(jié)點指針,因此我們便需要使用到二級指針去進(jìn)行一個控制
  • 但是呢,并不是所有的接口都需要使用到二級指針,像打印、查找、在pos結(jié)點之后插入和刪除結(jié)點這些操作,都是不會修改頭結(jié)點指針的,所以我們只需要以及指針就可以了

  • 然后再來說說斷言的情況,對于斷言,我們在接口的算法實現(xiàn)時也是用的即為頻繁,相信在這么多算法看下來后,你對斷言應(yīng)該是有了一個認(rèn)知了,當(dāng)你程序出問題的時候,它可以幫你快速定位程序的異常之處,這個功能對于大多數(shù)的程序員來說可是一個福音,網(wǎng)上都流傳著這么一句話【一杯茶、一包煙、一個Bug改一天】,這個話其實不無道理,因為在一些大型項目中,若是出現(xiàn)了一個Bug,因為很多代碼邏輯都是串聯(lián)的,可能你修改了這個Bug,另一個地方又出了Bug,這個時候其實assert斷言其實就可以幫助到我們很多,尤其是對于一些數(shù)組訪問越界、野指針訪問、空指針異常這些,若是你一步步去調(diào)試的話其實是很難找出來的,那用assert就很香了,馬上就給你報出來,而且哪一個【.cpp】文件的哪一行都會告訴你,于是程序員呼:assert實在是太棒了
  • 但是對于assert我們真的可以什么地方都使用嗎?當(dāng)然不是,可以看到,我在很多刪除算法的地方一般都會使用到assert,因為指針在不斷前移或者后移的情況下可能造成越界訪問,這個時候就會出現(xiàn)大問題了;還有一點的話就是我們通過找出來的【pos】位置去刪除其之前或之后的結(jié)點,對于這個傳進(jìn)來的【pos】指針可能是一個空指針,我們知道對空指針進(jìn)行操作是很危險的一件事,所以也需要斷言一下;最后一點的話可能就是對于二級指針接收的一級頭結(jié)點指針吧,對于傳進(jìn)來的頭結(jié)點指針我們也需要進(jìn)行一個判斷,尤其是在尾刪或者頭刪鏈表的地方,若是這個鏈表本身就是空的,那么如何對其進(jìn)行一個刪除呢?這其實也是一種對空指針的違法操作。有關(guān)如何斷言的操作我在前面已經(jīng)講過了,如還有不清楚的再去看看
  • 所以對于以上可能會出現(xiàn)問題的接口內(nèi)部一開始的地方就要進(jìn)行一個斷言,但是除了這些地方其實有些不需要斷言的地方你要平白無故地加上一個assert在前面,當(dāng)你的同事看到這個斷言的時候就會感到很詫異,例如說在pos位置前后去插入結(jié)點,這其實也沒必要斷言,因為可以進(jìn)行頭插和尾插,是不會出現(xiàn)非法操作的;在開發(fā)的過程中,我們也需要考慮到用戶的不當(dāng)操作,然后作出一些提醒,但是對于像某些場景比如說用戶在刪除一個文件時可能是一時的不當(dāng)操作,這個時候你就需要彈出一個對話框去告訴他是否需要繼續(xù)進(jìn)行操作,再讓他確認(rèn)一下,這樣顯得其實是比較合理的,但若是你直接在這個地方給出一個斷言,判斷用戶執(zhí)行了這個操作就直接報錯,那用戶可能就會被你嚇到了,影響用戶的體驗感
  • 所以說對于二級指針和斷言,并不是什么地方都可以使用,我們應(yīng)該在使用之前先做一個考慮和評估,看看在此處使用是否合理,真正地做到【因地制宜】,才能展現(xiàn)出邏輯型更強(qiáng)的代碼🐳

六、OJ題目實訓(xùn)

以下題目請通過我另一個專欄【LeetCode算法題解】觀看📺——題解更新中.<{=....

【LeetCode】21 - 合并兩個有序鏈表

【LeetCode】203 - 移除鏈表元素

鏈接

【LeetCode】206 - 反轉(zhuǎn)鏈表

【LeetCode】876 - 鏈表的中間結(jié)點

【牛客CM】11 - 鏈表分割

鏈接

【牛客JZ】22 - 鏈表中倒數(shù)第k個結(jié)點

七、總結(jié)與提煉

  • 最后,我們一起來回顧一下本文所學(xué)習(xí)的內(nèi)容。除題解外,本文大概使用了近四萬字左右的篇幅詳細(xì)講解了單鏈表相關(guān)的知識點
  • 首先分析了順序存儲結(jié)構(gòu)和鏈?zhǔn)酱鎯Y(jié)構(gòu)各自的優(yōu)缺點:對于【順序表】,雖然可以做到隨機(jī)快速訪問,但是對于數(shù)據(jù)的插入和刪除卻很麻煩;對于【鏈表】,雖然在插入和刪除這一塊無需像順序表那樣,只要修改next指針域的指向即可,但是對于鏈表而言不支持隨機(jī)訪問,需要從頭開始一一遍歷才可訪問到需訪問元素
  • 接著帶著大家先行去初步了解了有關(guān)鏈表的結(jié)構(gòu),從邏輯結(jié)構(gòu)和物理結(jié)構(gòu)講到了棧區(qū)和堆區(qū)的存儲原理,進(jìn)一步從底層的存儲加深了對鏈表的了解
  • 其次,開始了鏈表的各種接口算法實現(xiàn),這一部分是最核心,也是最重要的,學(xué)了鏈表,最重要的是要學(xué)會如何去使用,那對于其創(chuàng)建、銷毀、打印以及各種頭插、尾插、頭刪、尾刪等增刪查改操作,其中的核心代碼都是需要牢記心中
  • 最后,是帶大家做了一些在線OJ題目,來自【牛客】和【力扣】,這兩個在線OJ網(wǎng)站還是不錯的,推薦給大家,加深對知識的理解和掌握,這部分也是非常重要的,對于算法題,無論是在筆試還是面試中,也是除了基礎(chǔ)知識以外面試官極為看重的一部分,所以大家要早早開始刷題

OK,以上就是本文所要講解的全部內(nèi)容,非常感謝您的觀看,如有問題請于評論區(qū)留言或者私信我🌺

總結(jié)

以上是生活随笔為你收集整理的数据结构 | 单链表SingleList【带你从浅入深真正搞懂链表】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

国模大胆一区二区三区 | 乌克兰少妇xxxx做受 | 最新国产麻豆aⅴ精品无码 | 久久五月精品中文字幕 | 久久aⅴ免费观看 | 狂野欧美性猛xxxx乱大交 | 国产极品美女高潮无套在线观看 | 日韩精品a片一区二区三区妖精 | a国产一区二区免费入口 | 中文字幕无码热在线视频 | 中文字幕人成乱码熟女app | 蜜桃视频韩日免费播放 | 国产两女互慰高潮视频在线观看 | 欧美阿v高清资源不卡在线播放 | 一本久道久久综合婷婷五月 | 亲嘴扒胸摸屁股激烈网站 | 亚无码乱人伦一区二区 | 国产精品久久久久久亚洲影视内衣 | 蜜臀av在线播放 久久综合激激的五月天 | 亚洲无人区午夜福利码高清完整版 | 三上悠亚人妻中文字幕在线 | 三上悠亚人妻中文字幕在线 | 国产熟妇高潮叫床视频播放 | 亚洲精品成人av在线 | 最近的中文字幕在线看视频 | 在教室伦流澡到高潮hnp视频 | 久久五月精品中文字幕 | 人妻互换免费中文字幕 | 国产偷自视频区视频 | 国产午夜无码精品免费看 | 在线观看国产午夜福利片 | 中文无码精品a∨在线观看不卡 | 高清不卡一区二区三区 | 内射欧美老妇wbb | 色欲人妻aaaaaaa无码 | 99精品国产综合久久久久五月天 | 精品国产福利一区二区 | 亚洲欧美综合区丁香五月小说 | 精品欧美一区二区三区久久久 | 在线 国产 欧美 亚洲 天堂 | 色诱久久久久综合网ywww | 久久精品国产一区二区三区 | 国产在热线精品视频 | 永久免费观看国产裸体美女 | 国产人妻久久精品二区三区老狼 | 欧美亚洲国产一区二区三区 | 人人妻人人澡人人爽欧美一区九九 | 欧美午夜特黄aaaaaa片 | 欧美亚洲国产一区二区三区 | 国产农村乱对白刺激视频 | 蜜臀aⅴ国产精品久久久国产老师 | 国产美女极度色诱视频www | 欧洲精品码一区二区三区免费看 | 精品无码一区二区三区爱欲 | 亚洲精品鲁一鲁一区二区三区 | 免费国产成人高清在线观看网站 | 国产成人精品优优av | 麻豆精品国产精华精华液好用吗 | 亚洲综合另类小说色区 | 亚洲精品久久久久久一区二区 | 亚洲精品久久久久久一区二区 | 国产精品美女久久久网av | 好男人社区资源 | 樱花草在线社区www | 久久综合给久久狠狠97色 | 午夜免费福利小电影 | 久久亚洲中文字幕精品一区 | 四虎国产精品免费久久 | 精品无人国产偷自产在线 | 自拍偷自拍亚洲精品10p | 亚洲七七久久桃花影院 | 国产特级毛片aaaaaaa高清 | 玩弄中年熟妇正在播放 | 人妻尝试又大又粗久久 | 久久久久国色av免费观看性色 | 午夜无码区在线观看 | 欧美怡红院免费全部视频 | 欧美 日韩 亚洲 在线 | 国产精品久久久午夜夜伦鲁鲁 | 小泽玛莉亚一区二区视频在线 | 亚洲男人av香蕉爽爽爽爽 | 精品国产一区av天美传媒 | 中文字幕人成乱码熟女app | 亚洲aⅴ无码成人网站国产app | 国产人成高清在线视频99最全资源 | 国产网红无码精品视频 | 国产成人无码午夜视频在线观看 | 久久国产精品萌白酱免费 | 无码乱肉视频免费大全合集 | 性欧美疯狂xxxxbbbb | 免费看少妇作爱视频 | 国产在热线精品视频 | 国产亚洲日韩欧美另类第八页 | 亚洲一区二区三区偷拍女厕 | 99er热精品视频 | 亚洲 a v无 码免 费 成 人 a v | 无码人妻少妇伦在线电影 | 亚洲中文字幕乱码av波多ji | 欧美自拍另类欧美综合图片区 | 精品无人区无码乱码毛片国产 | 帮老师解开蕾丝奶罩吸乳网站 | 亚洲小说春色综合另类 | 国产成人无码区免费内射一片色欲 | 又大又硬又爽免费视频 | 99久久人妻精品免费二区 | 国产成人综合在线女婷五月99播放 | 牲欲强的熟妇农村老妇女视频 | 日韩精品无码免费一区二区三区 | 精品无码国产自产拍在线观看蜜 | 国产精品无码成人午夜电影 | 又大又黄又粗又爽的免费视频 | 人人妻人人藻人人爽欧美一区 | 国产精品办公室沙发 | 偷窥日本少妇撒尿chinese | 国产精品久久久久9999小说 | 国产精品久久久一区二区三区 | 日本精品久久久久中文字幕 | 久久久久成人精品免费播放动漫 | 东京热男人av天堂 | a国产一区二区免费入口 | 精品亚洲韩国一区二区三区 | 欧洲精品码一区二区三区免费看 | 精品久久久中文字幕人妻 | 国产精品人人爽人人做我的可爱 | 欧美猛少妇色xxxxx | 色诱久久久久综合网ywww | 中文字幕无码日韩专区 | 97资源共享在线视频 | 欧美午夜特黄aaaaaa片 | 人人妻在人人 | 亚洲精品一区国产 | 在线欧美精品一区二区三区 | 日日噜噜噜噜夜夜爽亚洲精品 | 亚洲s码欧洲m码国产av | 亚洲国产一区二区三区在线观看 | 美女扒开屁股让男人桶 | 久激情内射婷内射蜜桃人妖 | 夜夜影院未满十八勿进 | 中文字幕无线码免费人妻 | 日本精品少妇一区二区三区 | 久久综合九色综合97网 | 欧美 亚洲 国产 另类 | 在线 国产 欧美 亚洲 天堂 | 久久国产劲爆∧v内射 | av无码电影一区二区三区 | 中文字幕乱码人妻无码久久 | 久久熟妇人妻午夜寂寞影院 | 国产九九九九九九九a片 | 在线观看欧美一区二区三区 | 中文毛片无遮挡高清免费 | 中文字幕乱码中文乱码51精品 | a在线亚洲男人的天堂 | 成人免费视频视频在线观看 免费 | 人人爽人人澡人人人妻 | 强伦人妻一区二区三区视频18 | 国产精品久久福利网站 | 未满小14洗澡无码视频网站 | 欧美人与禽猛交狂配 | 婷婷丁香五月天综合东京热 | 亚洲gv猛男gv无码男同 | 丰满少妇女裸体bbw | 久久综合香蕉国产蜜臀av | 国产网红无码精品视频 | 亚洲啪av永久无码精品放毛片 | 精品熟女少妇av免费观看 | 无码纯肉视频在线观看 | 国产农村妇女高潮大叫 | 国产乱人无码伦av在线a | 国内精品人妻无码久久久影院 | 亚洲精品综合五月久久小说 | 日韩无套无码精品 | aⅴ在线视频男人的天堂 | 欧美人与禽zoz0性伦交 | 狠狠综合久久久久综合网 | 亚洲伊人久久精品影院 | 美女极度色诱视频国产 | 精品国产乱码久久久久乱码 | 一本久久a久久精品亚洲 | yw尤物av无码国产在线观看 | 欧美性黑人极品hd | 两性色午夜免费视频 | 人妻有码中文字幕在线 | 亚洲va欧美va天堂v国产综合 | 亚洲经典千人经典日产 | 沈阳熟女露脸对白视频 | 精品人妻av区 | 国产精品美女久久久久av爽李琼 | 国产人妻久久精品二区三区老狼 | 日日摸日日碰夜夜爽av | 内射爽无广熟女亚洲 | 亚洲大尺度无码无码专区 | 日韩av无码中文无码电影 | 丰满岳乱妇在线观看中字无码 | 亚洲の无码国产の无码影院 | 国产又粗又硬又大爽黄老大爷视 | 亚洲自偷自拍另类第1页 | 少妇性荡欲午夜性开放视频剧场 | 丁香花在线影院观看在线播放 | 少妇性俱乐部纵欲狂欢电影 | 一本久道高清无码视频 | 中文字幕日韩精品一区二区三区 | 亚洲色在线无码国产精品不卡 | 亚洲色www成人永久网址 | 日本精品人妻无码免费大全 | 国产成人av免费观看 | 久久天天躁夜夜躁狠狠 | 精品国产国产综合精品 | 国产高清av在线播放 | 中文字幕无码人妻少妇免费 | 55夜色66夜色国产精品视频 | 亚洲中文字幕久久无码 | 亚洲精品一区三区三区在线观看 | 亚洲精品久久久久avwww潮水 | 无套内谢的新婚少妇国语播放 | 四虎影视成人永久免费观看视频 | 国产精品亚洲一区二区三区喷水 | 全黄性性激高免费视频 | 国产精品99久久精品爆乳 | 色一情一乱一伦一区二区三欧美 | 男女爱爱好爽视频免费看 | 久久国内精品自在自线 | 国产精品无码成人午夜电影 | 99精品久久毛片a片 | 亚洲成a人一区二区三区 | 免费无码的av片在线观看 | 精品欧洲av无码一区二区三区 | 波多野42部无码喷潮在线 | 综合激情五月综合激情五月激情1 | 少妇无码一区二区二三区 | 丰满少妇弄高潮了www | 亚洲熟妇色xxxxx亚洲 | 国产卡一卡二卡三 | 人妻少妇精品视频专区 | 男女下面进入的视频免费午夜 | 国产精品无套呻吟在线 | 亚洲 欧美 激情 小说 另类 | 婷婷五月综合激情中文字幕 | 一本久久a久久精品vr综合 | 国产97色在线 | 免 | 日日摸日日碰夜夜爽av | 国产精品美女久久久网av | 色妞www精品免费视频 | 女高中生第一次破苞av | 久久人人爽人人爽人人片av高清 | 狠狠色丁香久久婷婷综合五月 | 熟妇人妻无码xxx视频 | 中文字幕乱码亚洲无线三区 | 久久97精品久久久久久久不卡 | 暴力强奷在线播放无码 | 人妻少妇精品无码专区动漫 | 久久99国产综合精品 | 久久久久久久久蜜桃 | 欧美精品无码一区二区三区 | 少妇人妻大乳在线视频 | 美女毛片一区二区三区四区 | 无码人妻少妇伦在线电影 | 中文无码伦av中文字幕 | 成人欧美一区二区三区黑人 | 最新国产麻豆aⅴ精品无码 | a国产一区二区免费入口 | 亚洲娇小与黑人巨大交 | 亚洲国产av精品一区二区蜜芽 | 精品国产av色一区二区深夜久久 | 国产日产欧产精品精品app | 久久人妻内射无码一区三区 | 午夜精品久久久久久久久 | 国产真实乱对白精彩久久 | 久久zyz资源站无码中文动漫 | 国色天香社区在线视频 | 夜精品a片一区二区三区无码白浆 | 特黄特色大片免费播放器图片 | 欧美喷潮久久久xxxxx | 亚洲中文无码av永久不收费 | 日日天日日夜日日摸 | 欧美一区二区三区视频在线观看 | 3d动漫精品啪啪一区二区中 | 一本久道久久综合狠狠爱 | 九九在线中文字幕无码 | 国产9 9在线 | 中文 | 亚洲精品国偷拍自产在线观看蜜桃 | 欧美国产日产一区二区 | 99久久人妻精品免费一区 | 欧美放荡的少妇 | аⅴ资源天堂资源库在线 | 国产精品国产自线拍免费软件 | 亚洲欧美国产精品专区久久 | 黑人巨大精品欧美黑寡妇 | 国产精品二区一区二区aⅴ污介绍 | 我要看www免费看插插视频 | 中文字幕+乱码+中文字幕一区 | 国产色精品久久人妻 | 国产香蕉97碰碰久久人人 | 免费无码的av片在线观看 | 国产成人一区二区三区别 | 亚洲日本va中文字幕 | a片免费视频在线观看 | 久久亚洲中文字幕无码 | 精品夜夜澡人妻无码av蜜桃 | 在线欧美精品一区二区三区 | 中文字幕无码热在线视频 | 亚洲成av人片天堂网无码】 | 18黄暴禁片在线观看 | 狂野欧美激情性xxxx | 中文字幕人成乱码熟女app | 国产精品欧美成人 | 男女下面进入的视频免费午夜 | 在线播放无码字幕亚洲 | 狠狠色色综合网站 | 综合网日日天干夜夜久久 | 狠狠色噜噜狠狠狠狠7777米奇 | 性欧美牲交xxxxx视频 | 澳门永久av免费网站 | 中文精品无码中文字幕无码专区 | 国产亚洲视频中文字幕97精品 | 亚洲熟妇色xxxxx欧美老妇y | 在线看片无码永久免费视频 | 国产精品a成v人在线播放 | 成人性做爰aaa片免费看不忠 | 欧美老妇交乱视频在线观看 | 老司机亚洲精品影院 | 任你躁在线精品免费 | 国产精品国产三级国产专播 | 中文字幕日产无线码一区 | 夜精品a片一区二区三区无码白浆 | 亚洲精品鲁一鲁一区二区三区 | 又黄又爽又色的视频 | 精品偷自拍另类在线观看 | 日日摸天天摸爽爽狠狠97 | 日本熟妇人妻xxxxx人hd | 国产艳妇av在线观看果冻传媒 | 亚洲欧洲日本无在线码 | 在线看片无码永久免费视频 | 精品 日韩 国产 欧美 视频 | 精品人妻中文字幕有码在线 | 亚洲欧洲日本综合aⅴ在线 | 日韩亚洲欧美精品综合 | 亚洲人交乣女bbw | 蜜桃av抽搐高潮一区二区 | 久久伊人色av天堂九九小黄鸭 | 国产真实夫妇视频 | www国产亚洲精品久久网站 | 狠狠色噜噜狠狠狠狠7777米奇 | 波多野结衣高清一区二区三区 | 国产亚洲精品久久久久久久 | 亚洲の无码国产の无码影院 | 精品人人妻人人澡人人爽人人 | 国色天香社区在线视频 | 国产精品久久久久7777 | 欧洲欧美人成视频在线 | 成人性做爰aaa片免费看不忠 | 1000部啪啪未满十八勿入下载 | 国产人妻大战黑人第1集 | 国产免费久久精品国产传媒 | 国产精品国产自线拍免费软件 | 伊人久久婷婷五月综合97色 | 无码国内精品人妻少妇 | 久久亚洲中文字幕精品一区 | 熟妇女人妻丰满少妇中文字幕 | 全黄性性激高免费视频 | 鲁一鲁av2019在线 | 成人无码视频免费播放 | 老司机亚洲精品影院 | 一本久久a久久精品vr综合 | 西西人体www44rt大胆高清 | 久久综合给合久久狠狠狠97色 | 鲁大师影院在线观看 | 午夜精品久久久久久久久 | 久久99精品国产.久久久久 | 成人一区二区免费视频 | 国产热a欧美热a在线视频 | 天堂а√在线地址中文在线 | 欧美三级a做爰在线观看 | 色欲av亚洲一区无码少妇 | 久久97精品久久久久久久不卡 | 国产精品内射视频免费 | 日韩av无码中文无码电影 | 大胆欧美熟妇xx | 国产av一区二区精品久久凹凸 | 一本久久a久久精品亚洲 | 国产色xx群视频射精 | 欧美喷潮久久久xxxxx | 国产成人亚洲综合无码 | aⅴ在线视频男人的天堂 | 纯爱无遮挡h肉动漫在线播放 | 中文字幕日产无线码一区 | 美女毛片一区二区三区四区 | 国产三级久久久精品麻豆三级 | 99久久精品日本一区二区免费 | 宝宝好涨水快流出来免费视频 | 熟妇人妻激情偷爽文 | 青青草原综合久久大伊人精品 | 亚洲日本在线电影 | 久久婷婷五月综合色国产香蕉 | 精品国产成人一区二区三区 | 欧洲熟妇色 欧美 | 日本精品人妻无码免费大全 | 丰满岳乱妇在线观看中字无码 | 久久久中文久久久无码 | 98国产精品综合一区二区三区 | 亚洲熟熟妇xxxx | 最新国产麻豆aⅴ精品无码 | 少妇的肉体aa片免费 | 无码乱肉视频免费大全合集 | 国产免费久久久久久无码 | 少妇人妻偷人精品无码视频 | 成人无码视频免费播放 | 久久亚洲精品中文字幕无男同 | 精品人妻人人做人人爽夜夜爽 | 又大又硬又爽免费视频 | 国产成人无码av在线影院 | 午夜福利电影 | 欧美激情综合亚洲一二区 | 日本www一道久久久免费榴莲 | 国产精品-区区久久久狼 | 国产农村妇女高潮大叫 | 麻豆精产国品 | 欧美国产日产一区二区 | 性色欲情网站iwww九文堂 | 呦交小u女精品视频 | 蜜桃无码一区二区三区 | 久久久久久a亚洲欧洲av冫 | 中文字幕乱码亚洲无线三区 | 又粗又大又硬毛片免费看 | 欧美 丝袜 自拍 制服 另类 | 欧美精品国产综合久久 | 欧美精品免费观看二区 | 伊在人天堂亚洲香蕉精品区 | 国产精品亚洲一区二区三区喷水 | 国产精品国产三级国产专播 | 对白脏话肉麻粗话av | 狠狠综合久久久久综合网 | 国产猛烈高潮尖叫视频免费 | 亚洲色欲色欲欲www在线 | 国产午夜无码精品免费看 | 国产无遮挡吃胸膜奶免费看 | 最新国产乱人伦偷精品免费网站 | 欧美精品国产综合久久 | 亚拍精品一区二区三区探花 | 国产疯狂伦交大片 | 成人无码视频在线观看网站 | 麻豆md0077饥渴少妇 | 香蕉久久久久久av成人 | 九九在线中文字幕无码 | 国产无遮挡又黄又爽免费视频 | 装睡被陌生人摸出水好爽 | 国产尤物精品视频 | 国产人妻精品一区二区三区不卡 | 亚洲男人av香蕉爽爽爽爽 | 久久精品一区二区三区四区 | 久久婷婷五月综合色国产香蕉 | 免费看少妇作爱视频 | 999久久久国产精品消防器材 | 麻豆国产97在线 | 欧洲 | 欧美亚洲日韩国产人成在线播放 | 玩弄中年熟妇正在播放 | 日本熟妇人妻xxxxx人hd | 国产成人一区二区三区别 | 日本爽爽爽爽爽爽在线观看免 | 强伦人妻一区二区三区视频18 | 亚洲人成网站免费播放 | 欧美乱妇无乱码大黄a片 | 自拍偷自拍亚洲精品10p | 成人精品一区二区三区中文字幕 | 内射老妇bbwx0c0ck | 又色又爽又黄的美女裸体网站 | 欧美日韩视频无码一区二区三 | 免费观看又污又黄的网站 | 精品一二三区久久aaa片 | 精品久久久中文字幕人妻 | www一区二区www免费 | 久久熟妇人妻午夜寂寞影院 | 国产成人无码av一区二区 | 国内精品久久毛片一区二区 | 国产成人无码av片在线观看不卡 | 亚洲精品成a人在线观看 | 亚洲欧美日韩国产精品一区二区 | 久久精品中文字幕大胸 | 亚洲欧美中文字幕5发布 | 精品熟女少妇av免费观看 | 国产极品视觉盛宴 | 中文字幕乱妇无码av在线 | 成人毛片一区二区 | 美女黄网站人色视频免费国产 | 亚洲精品国产精品乱码视色 | 国产无av码在线观看 | 久久久久国色av免费观看性色 | 国产乱子伦视频在线播放 | 日本丰满护士爆乳xxxx | 久久综合狠狠综合久久综合88 | 国产精品久久久一区二区三区 | 亚洲国产精品一区二区美利坚 | 国产三级久久久精品麻豆三级 | 久久久久亚洲精品男人的天堂 | 国产精品无码成人午夜电影 | 中文字幕日韩精品一区二区三区 | 色欲人妻aaaaaaa无码 | 无套内谢的新婚少妇国语播放 | 国产精品内射视频免费 | 无码免费一区二区三区 | 四虎影视成人永久免费观看视频 | 国产午夜手机精彩视频 | 女人和拘做爰正片视频 | 东京热无码av男人的天堂 | 高清无码午夜福利视频 | 精品欧洲av无码一区二区三区 | 青青久在线视频免费观看 | 奇米影视7777久久精品人人爽 | 国产亚洲欧美日韩亚洲中文色 | 国产精品久久久久7777 | 天堂无码人妻精品一区二区三区 | 少妇激情av一区二区 | 一个人免费观看的www视频 | 九九久久精品国产免费看小说 | 国产在线一区二区三区四区五区 | 无码帝国www无码专区色综合 | 亚洲中文字幕无码一久久区 | 国产精品无码一区二区桃花视频 | 精品国产一区二区三区四区在线看 | 久青草影院在线观看国产 | 久久亚洲中文字幕精品一区 | 超碰97人人做人人爱少妇 | 丰满岳乱妇在线观看中字无码 | 亚洲国产精品毛片av不卡在线 | 国产精品人人妻人人爽 | 亚洲精品成人福利网站 | 午夜熟女插插xx免费视频 | 色五月五月丁香亚洲综合网 | 久久午夜无码鲁丝片午夜精品 | 日韩av无码一区二区三区不卡 | 丰满妇女强制高潮18xxxx | 国产区女主播在线观看 | 帮老师解开蕾丝奶罩吸乳网站 | 小sao货水好多真紧h无码视频 | 国产情侣作爱视频免费观看 | 精品午夜福利在线观看 | 无码人妻av免费一区二区三区 | 99精品视频在线观看免费 | 性色欲网站人妻丰满中文久久不卡 | 又紧又大又爽精品一区二区 | 久久精品国产精品国产精品污 | 丰满少妇女裸体bbw | 日欧一片内射va在线影院 | 99麻豆久久久国产精品免费 | 在线天堂新版最新版在线8 | 午夜不卡av免费 一本久久a久久精品vr综合 | 亚洲日韩中文字幕在线播放 | 色综合久久88色综合天天 | 六月丁香婷婷色狠狠久久 | 亚洲成a人一区二区三区 | 日韩少妇内射免费播放 | 日韩人妻无码一区二区三区久久99 | 女人被爽到呻吟gif动态图视看 | 在线观看欧美一区二区三区 | 清纯唯美经典一区二区 | a国产一区二区免费入口 | 天天拍夜夜添久久精品大 | 呦交小u女精品视频 | 成 人影片 免费观看 | 欧美日韩人成综合在线播放 | 夫妻免费无码v看片 | 少妇邻居内射在线 | 亚洲午夜福利在线观看 | 精品偷自拍另类在线观看 | 精品无码国产自产拍在线观看蜜 | 动漫av网站免费观看 | 亚洲国产一区二区三区在线观看 | 在线亚洲高清揄拍自拍一品区 | 亚洲中文字幕久久无码 | 国内少妇偷人精品视频免费 | 国产精品无码一区二区三区不卡 | 亚洲 另类 在线 欧美 制服 | 我要看www免费看插插视频 | 日韩av无码一区二区三区不卡 | 久久www免费人成人片 | 成人女人看片免费视频放人 | 欧美大屁股xxxxhd黑色 | 兔费看少妇性l交大片免费 | 亚洲精品欧美二区三区中文字幕 | 欧美一区二区三区视频在线观看 | 中文字幕乱码人妻无码久久 | 国产成人无码a区在线观看视频app | 特级做a爰片毛片免费69 | 欧美人与禽zoz0性伦交 | 波多野结衣高清一区二区三区 | 99国产精品白浆在线观看免费 | 国产激情艳情在线看视频 | 黑人巨大精品欧美黑寡妇 | 国产国语老龄妇女a片 | 无码精品人妻一区二区三区av | 强伦人妻一区二区三区视频18 | 久久久av男人的天堂 | 久久精品人妻少妇一区二区三区 | 亚洲一区二区三区四区 | 日韩在线不卡免费视频一区 | 久久久成人毛片无码 | 成年女人永久免费看片 | 国产suv精品一区二区五 | 久久人人97超碰a片精品 | 秋霞成人午夜鲁丝一区二区三区 | 亚洲精品鲁一鲁一区二区三区 | 精品国产成人一区二区三区 | 国产午夜手机精彩视频 | 日本高清一区免费中文视频 | 午夜理论片yy44880影院 | 丰满岳乱妇在线观看中字无码 | 红桃av一区二区三区在线无码av | 丰满诱人的人妻3 | 亚洲中文无码av永久不收费 | 亚洲成色www久久网站 | 无码纯肉视频在线观看 | 天天做天天爱天天爽综合网 | 久久久久成人片免费观看蜜芽 | 日产精品99久久久久久 | 无码国内精品人妻少妇 | 国产乱人伦av在线无码 | 国产免费无码一区二区视频 | 亚洲成av人片在线观看无码不卡 | 国产成人无码a区在线观看视频app | 亚洲男女内射在线播放 | 伊人久久大香线蕉午夜 | 狠狠色丁香久久婷婷综合五月 | 四虎永久在线精品免费网址 | 国产精品高潮呻吟av久久 | 丰满岳乱妇在线观看中字无码 | 国产亚洲视频中文字幕97精品 | 少妇厨房愉情理9仑片视频 | 国产成人人人97超碰超爽8 | а√天堂www在线天堂小说 | 偷窥日本少妇撒尿chinese | 亚洲精品一区二区三区大桥未久 | 久久久久成人精品免费播放动漫 | 日产精品99久久久久久 | 人人妻人人澡人人爽欧美一区九九 | 狠狠躁日日躁夜夜躁2020 | 未满小14洗澡无码视频网站 | 国产偷国产偷精品高清尤物 | 乱人伦人妻中文字幕无码久久网 | 波多野结衣aⅴ在线 | 小泽玛莉亚一区二区视频在线 | 男女下面进入的视频免费午夜 | 性色av无码免费一区二区三区 | 色噜噜亚洲男人的天堂 | 日本va欧美va欧美va精品 | 精品偷自拍另类在线观看 | 久久97精品久久久久久久不卡 | 狠狠噜狠狠狠狠丁香五月 | 巨爆乳无码视频在线观看 | 人妻无码αv中文字幕久久琪琪布 | 丰满护士巨好爽好大乳 | 成人免费视频视频在线观看 免费 | 亚洲国产高清在线观看视频 | 中文字幕乱妇无码av在线 | 中文无码伦av中文字幕 | 国产成人综合美国十次 | 亚洲欧美中文字幕5发布 | 黑人玩弄人妻中文在线 | 中文字幕无码日韩欧毛 | 成 人 免费观看网站 | 日本一区二区三区免费高清 | 亚洲熟妇色xxxxx欧美老妇 | 伊人色综合久久天天小片 | 亚洲s码欧洲m码国产av | 4hu四虎永久在线观看 | 精品无人国产偷自产在线 | 丝袜人妻一区二区三区 | 强辱丰满人妻hd中文字幕 | 国产精品亚洲lv粉色 | 欧洲极品少妇 | 亚洲精品午夜国产va久久成人 | www国产亚洲精品久久久日本 | 中国女人内谢69xxxxxa片 | 午夜精品一区二区三区在线观看 | 国产在线精品一区二区高清不卡 | 18无码粉嫩小泬无套在线观看 | 亚洲日韩一区二区 | 亚洲精品综合五月久久小说 | 波多野结衣av在线观看 | 成在人线av无码免观看麻豆 | 久久久久人妻一区精品色欧美 | 2019nv天堂香蕉在线观看 | 精品一二三区久久aaa片 | 两性色午夜视频免费播放 | 日韩精品a片一区二区三区妖精 | 天干天干啦夜天干天2017 | 亚洲综合伊人久久大杳蕉 | 青青久在线视频免费观看 | 欧美人与牲动交xxxx | 中国女人内谢69xxxxxa片 | 亚洲精品无码国产 | 性欧美大战久久久久久久 | a在线亚洲男人的天堂 | 国产亚洲精品久久久闺蜜 | 国产亚洲人成a在线v网站 | 国产成人综合美国十次 | 日韩av无码一区二区三区 | 曰本女人与公拘交酡免费视频 | 国产精品无码一区二区桃花视频 | 日韩av激情在线观看 | 天堂а√在线地址中文在线 | 亚洲va中文字幕无码久久不卡 | 国产美女精品一区二区三区 | 初尝人妻少妇中文字幕 | 色偷偷人人澡人人爽人人模 | 婷婷五月综合激情中文字幕 | 国产国产精品人在线视 | 97精品人妻一区二区三区香蕉 | 国产av无码专区亚洲a∨毛片 | 亚洲娇小与黑人巨大交 | 国产精品久久久久久久9999 | 久久久国产精品无码免费专区 | 精品日本一区二区三区在线观看 | 久久亚洲精品成人无码 | 牲欲强的熟妇农村老妇女视频 | 国产在线精品一区二区高清不卡 | 夜夜影院未满十八勿进 | 亚洲爆乳无码专区 | 久青草影院在线观看国产 | 美女黄网站人色视频免费国产 | 国产香蕉97碰碰久久人人 | 55夜色66夜色国产精品视频 | 蜜桃臀无码内射一区二区三区 | 性做久久久久久久久 | 久久久久免费精品国产 | 超碰97人人做人人爱少妇 | 精品人妻av区 | 2020久久超碰国产精品最新 | 精品人妻中文字幕有码在线 | 久久亚洲中文字幕精品一区 | 国产九九九九九九九a片 | аⅴ资源天堂资源库在线 | 日本护士毛茸茸高潮 | 精品国产av色一区二区深夜久久 | 亚洲无人区一区二区三区 | 天天躁夜夜躁狠狠是什么心态 | 久青草影院在线观看国产 | 精品久久久无码中文字幕 | 精品国产一区二区三区av 性色 | 国产明星裸体无码xxxx视频 | 天干天干啦夜天干天2017 | 欧美人与牲动交xxxx | 装睡被陌生人摸出水好爽 | 黑人玩弄人妻中文在线 | 国产亲子乱弄免费视频 | 无码人妻出轨黑人中文字幕 | 国产成人综合在线女婷五月99播放 | 久久久久成人片免费观看蜜芽 | 一本加勒比波多野结衣 | 国产国语老龄妇女a片 | 久久久www成人免费毛片 | 精品欧美一区二区三区久久久 | 男人和女人高潮免费网站 | 日本欧美一区二区三区乱码 | 又大又紧又粉嫩18p少妇 | 亚洲第一网站男人都懂 | 久久久久亚洲精品中文字幕 | 亚洲 高清 成人 动漫 | 亚洲中文字幕无码中字 | 国产精品人人妻人人爽 | 无码纯肉视频在线观看 | 久久久av男人的天堂 | 色综合久久88色综合天天 | 欧美国产亚洲日韩在线二区 | 亚洲国产精品成人久久蜜臀 | 亚洲日韩av一区二区三区中文 | 亚洲成色www久久网站 | 狠狠亚洲超碰狼人久久 | 中文字幕无码视频专区 | 亚洲综合在线一区二区三区 | 欧美黑人性暴力猛交喷水 | 天天摸天天碰天天添 | 婷婷综合久久中文字幕蜜桃三电影 | 俺去俺来也在线www色官网 | 久久亚洲中文字幕无码 | 麻豆国产人妻欲求不满谁演的 | 久久精品国产精品国产精品污 | 亚洲欧美色中文字幕在线 | 色偷偷av老熟女 久久精品人妻少妇一区二区三区 | a国产一区二区免费入口 | 亚洲欧美日韩成人高清在线一区 | 特级做a爰片毛片免费69 | 老司机亚洲精品影院 | 国产精品无套呻吟在线 | 天堂无码人妻精品一区二区三区 | 国产亚av手机在线观看 | 99久久精品日本一区二区免费 | 欧美三级a做爰在线观看 | 最近的中文字幕在线看视频 | 无码人妻av免费一区二区三区 | 国产亚洲精品久久久ai换 | 妺妺窝人体色www婷婷 | 波多野结衣aⅴ在线 | 色五月丁香五月综合五月 | 伊人久久婷婷五月综合97色 | 真人与拘做受免费视频一 | 免费无码午夜福利片69 | 亚洲一区二区三区在线观看网站 | 女人和拘做爰正片视频 | 丁香啪啪综合成人亚洲 | 精品无人区无码乱码毛片国产 | 亚洲日本一区二区三区在线 | 久久99精品久久久久婷婷 | 青青青手机频在线观看 | 扒开双腿吃奶呻吟做受视频 | a在线亚洲男人的天堂 | 桃花色综合影院 | 国产午夜亚洲精品不卡下载 | 任你躁在线精品免费 | 鲁鲁鲁爽爽爽在线视频观看 | 日本乱人伦片中文三区 | 色诱久久久久综合网ywww | 国精产品一区二区三区 | 日日躁夜夜躁狠狠躁 | 亚洲 另类 在线 欧美 制服 | 久久久久久九九精品久 | 狂野欧美激情性xxxx | 日产精品高潮呻吟av久久 | 小泽玛莉亚一区二区视频在线 | 国产成人精品三级麻豆 | 永久黄网站色视频免费直播 | 日韩在线不卡免费视频一区 | 漂亮人妻洗澡被公强 日日躁 | 美女毛片一区二区三区四区 | 熟妇人妻无码xxx视频 | 国产乱人伦偷精品视频 | 骚片av蜜桃精品一区 | 午夜无码人妻av大片色欲 | 一本加勒比波多野结衣 | 国产真人无遮挡作爱免费视频 | 精品人妻中文字幕有码在线 | аⅴ资源天堂资源库在线 | 玩弄中年熟妇正在播放 | 亚洲 欧美 激情 小说 另类 | 人妻体内射精一区二区三四 | 男女猛烈xx00免费视频试看 | 国产特级毛片aaaaaaa高清 | 一本久久a久久精品亚洲 | 狠狠色噜噜狠狠狠7777奇米 | 粗大的内捧猛烈进出视频 | 日韩少妇内射免费播放 | 熟女少妇人妻中文字幕 | 亚洲色大成网站www国产 | 欧美一区二区三区视频在线观看 | 久久国产精品精品国产色婷婷 | 国语精品一区二区三区 | 亚洲无人区一区二区三区 | 日本精品高清一区二区 | 中文字幕 亚洲精品 第1页 | 亚洲色在线无码国产精品不卡 | 国产精品久久精品三级 | 日本熟妇乱子伦xxxx | 性欧美大战久久久久久久 | 在线播放免费人成毛片乱码 | 西西人体www44rt大胆高清 | 精品厕所偷拍各类美女tp嘘嘘 | 台湾无码一区二区 | 成熟女人特级毛片www免费 | 国产一区二区三区四区五区加勒比 | 高潮喷水的毛片 | 4hu四虎永久在线观看 | 一个人看的www免费视频在线观看 | 夜夜躁日日躁狠狠久久av | 国产欧美精品一区二区三区 | 国产sm调教视频在线观看 | 国产亚洲tv在线观看 | 少妇性俱乐部纵欲狂欢电影 | 精品一区二区三区波多野结衣 | 在教室伦流澡到高潮hnp视频 | 国产情侣作爱视频免费观看 | 成人免费视频在线观看 | 国产高潮视频在线观看 | 国产成人人人97超碰超爽8 | 老熟妇乱子伦牲交视频 | 性史性农村dvd毛片 | 久久99精品国产麻豆 | 99国产欧美久久久精品 | 宝宝好涨水快流出来免费视频 | 精品乱码久久久久久久 | 特级做a爰片毛片免费69 | 国产sm调教视频在线观看 | 任你躁在线精品免费 | 久久久www成人免费毛片 | 亚洲精品国产精品乱码不卡 | 欧美日韩久久久精品a片 | 少妇性俱乐部纵欲狂欢电影 | 成人精品一区二区三区中文字幕 | 亚洲成av人片在线观看无码不卡 | 国产三级久久久精品麻豆三级 | 男人的天堂2018无码 | 色爱情人网站 | 亚洲精品一区三区三区在线观看 | 麻豆蜜桃av蜜臀av色欲av | 夜精品a片一区二区三区无码白浆 | 一本加勒比波多野结衣 | 秋霞成人午夜鲁丝一区二区三区 | 亚洲呦女专区 | 国产人妻精品午夜福利免费 | 丁香花在线影院观看在线播放 | 中文字幕久久久久人妻 | 欧美怡红院免费全部视频 | 熟妇人妻中文av无码 | 无码人妻精品一区二区三区不卡 | 人人妻人人澡人人爽人人精品 | 国产精品久久精品三级 | 精品国产青草久久久久福利 | 久久无码中文字幕免费影院蜜桃 | 午夜无码人妻av大片色欲 | 无码av中文字幕免费放 | 欧美 日韩 亚洲 在线 | 成人免费无码大片a毛片 | 国产精品毛多多水多 | 国产成人综合色在线观看网站 | 蜜桃视频插满18在线观看 | 日本精品少妇一区二区三区 | 狠狠色色综合网站 | 欧美日本免费一区二区三区 | 久久97精品久久久久久久不卡 | 狠狠色噜噜狠狠狠狠7777米奇 | 任你躁国产自任一区二区三区 | 97精品人妻一区二区三区香蕉 | 亚洲一区二区三区播放 | 国产精品久久久久久亚洲影视内衣 | 午夜精品久久久内射近拍高清 | 日韩精品a片一区二区三区妖精 | 婷婷丁香六月激情综合啪 | 亚洲成av人在线观看网址 | 国语精品一区二区三区 | 色狠狠av一区二区三区 | 欧洲精品码一区二区三区免费看 | 国产猛烈高潮尖叫视频免费 | 亚洲综合另类小说色区 | 日韩精品无码免费一区二区三区 | 免费人成在线观看网站 | 无码国产激情在线观看 | 成人欧美一区二区三区黑人 | 欧美性生交活xxxxxdddd | 亚洲国精产品一二二线 | 亚欧洲精品在线视频免费观看 | 成人欧美一区二区三区黑人 | 学生妹亚洲一区二区 | 99久久精品日本一区二区免费 | 红桃av一区二区三区在线无码av | 精品无码国产一区二区三区av | 日韩亚洲欧美精品综合 | 在线а√天堂中文官网 | 中文字幕无码人妻少妇免费 | 日韩精品无码免费一区二区三区 | 又大又硬又黄的免费视频 | 无码精品人妻一区二区三区av | 国语自产偷拍精品视频偷 | 午夜不卡av免费 一本久久a久久精品vr综合 | 亚洲七七久久桃花影院 | 人人妻人人澡人人爽人人精品 | 亚洲日本va中文字幕 | 无码一区二区三区在线 | 国产熟女一区二区三区四区五区 | 国产福利视频一区二区 | 精品久久综合1区2区3区激情 | 国产精品手机免费 | 在线精品国产一区二区三区 | 麻豆精品国产精华精华液好用吗 | 内射后入在线观看一区 | 狠狠色噜噜狠狠狠7777奇米 | 色欲综合久久中文字幕网 | 成人性做爰aaa片免费看不忠 | 欧美大屁股xxxxhd黑色 | 国产精品久久久一区二区三区 | 人妻熟女一区 | 日韩av无码一区二区三区 | 人妻少妇精品视频专区 | 2019午夜福利不卡片在线 | 色综合久久88色综合天天 | 狠狠色噜噜狠狠狠7777奇米 | 蜜桃无码一区二区三区 | 亚洲精品国偷拍自产在线观看蜜桃 | 麻豆成人精品国产免费 | 久青草影院在线观看国产 | 中文毛片无遮挡高清免费 | 日日摸天天摸爽爽狠狠97 | 激情综合激情五月俺也去 | 中文字幕乱码人妻二区三区 | 国产激情精品一区二区三区 | 激情亚洲一区国产精品 | 国产在线精品一区二区三区直播 | 国产区女主播在线观看 | 在线精品国产一区二区三区 | 亚洲中文字幕无码一久久区 | 荡女精品导航 | 在线精品国产一区二区三区 | 99久久精品国产一区二区蜜芽 | 国产又粗又硬又大爽黄老大爷视 | 欧洲美熟女乱又伦 | 亚洲精品成人av在线 | 精品无码国产一区二区三区av | 99久久人妻精品免费二区 | 乱码午夜-极国产极内射 | 欧美日韩综合一区二区三区 | 中文字幕乱妇无码av在线 | 性色av无码免费一区二区三区 | 中文字幕av伊人av无码av | 性欧美熟妇videofreesex | 成年女人永久免费看片 | 亚洲色成人中文字幕网站 | 国产九九九九九九九a片 | 国产精品无码mv在线观看 | 国产av无码专区亚洲awww | 成人欧美一区二区三区 | av无码久久久久不卡免费网站 | 少妇人妻偷人精品无码视频 | 久久国产精品精品国产色婷婷 | 清纯唯美经典一区二区 | 中文字幕日产无线码一区 | 色婷婷综合中文久久一本 | 激情内射日本一区二区三区 | 无码人妻黑人中文字幕 | 亚洲男人av天堂午夜在 | 激情人妻另类人妻伦 | 中文久久乱码一区二区 | 国产精品人妻一区二区三区四 | 成人欧美一区二区三区黑人免费 | 亚洲а∨天堂久久精品2021 | 少妇一晚三次一区二区三区 | 狠狠色噜噜狠狠狠狠7777米奇 | 暴力强奷在线播放无码 | 欧洲熟妇色 欧美 | 无码人妻少妇伦在线电影 | 国产乱码精品一品二品 | 精品久久久久久亚洲精品 | 亚洲熟熟妇xxxx | 精品欧美一区二区三区久久久 | 国产69精品久久久久app下载 | 特黄特色大片免费播放器图片 | 在线视频网站www色 | 色婷婷综合激情综在线播放 | 三级4级全黄60分钟 | 成 人 网 站国产免费观看 | 中文字幕av无码一区二区三区电影 | 中文精品无码中文字幕无码专区 | 人人超人人超碰超国产 | 国内综合精品午夜久久资源 | 亚洲色欲色欲欲www在线 | 99久久人妻精品免费二区 | 久久精品国产精品国产精品污 | 国产国产精品人在线视 | 夜夜躁日日躁狠狠久久av | 欧美野外疯狂做受xxxx高潮 | 超碰97人人做人人爱少妇 | 5858s亚洲色大成网站www | 狠狠躁日日躁夜夜躁2020 | 国产亚洲美女精品久久久2020 | 在线а√天堂中文官网 | 国产精品怡红院永久免费 | 中文字幕精品av一区二区五区 | 97资源共享在线视频 | 扒开双腿疯狂进出爽爽爽视频 | 亚洲午夜福利在线观看 | 无码人妻丰满熟妇区五十路百度 | 波多野结衣av一区二区全免费观看 | 国产成人无码av片在线观看不卡 | 精品人妻中文字幕有码在线 | 成人av无码一区二区三区 | 欧洲精品码一区二区三区免费看 | 亚洲一区二区三区播放 | 色一情一乱一伦一视频免费看 | 鲁鲁鲁爽爽爽在线视频观看 | 国产人妻久久精品二区三区老狼 | 亚洲欧美日韩成人高清在线一区 | 色一情一乱一伦一视频免费看 | 捆绑白丝粉色jk震动捧喷白浆 | 久久精品中文闷骚内射 | 天天摸天天碰天天添 | 精品成在人线av无码免费看 | 精品国产精品久久一区免费式 | 国产性猛交╳xxx乱大交 国产精品久久久久久无码 欧洲欧美人成视频在线 | 精品久久久久香蕉网 | 老子影院午夜伦不卡 | 成人动漫在线观看 | 人妻无码久久精品人妻 | 西西人体www44rt大胆高清 | 99久久精品国产一区二区蜜芽 | 极品尤物被啪到呻吟喷水 | 精品 日韩 国产 欧美 视频 | 99久久99久久免费精品蜜桃 | 国产一区二区三区精品视频 | 欧美人与禽猛交狂配 | 国语精品一区二区三区 | 亚洲成a人片在线观看无码3d | 西西人体www44rt大胆高清 | 久久 国产 尿 小便 嘘嘘 | 领导边摸边吃奶边做爽在线观看 | 国产农村乱对白刺激视频 | 国产一精品一av一免费 | 国产成人午夜福利在线播放 | 日韩欧美中文字幕在线三区 | 特级做a爰片毛片免费69 | 久久久国产精品无码免费专区 | 天天燥日日燥 | 久久99久久99精品中文字幕 | 亚洲一区二区三区在线观看网站 | 精品夜夜澡人妻无码av蜜桃 | 欧美变态另类xxxx | 国产高清不卡无码视频 | 人妻少妇精品无码专区动漫 | 又大又紧又粉嫩18p少妇 | 永久黄网站色视频免费直播 | 国产激情无码一区二区 | 黑人巨大精品欧美一区二区 | 免费看少妇作爱视频 | www成人国产高清内射 | 女人和拘做爰正片视频 | 丝袜美腿亚洲一区二区 | 国产 浪潮av性色四虎 | 色婷婷香蕉在线一区二区 | 岛国片人妻三上悠亚 | 午夜成人1000部免费视频 | 国产超碰人人爽人人做人人添 | 狠狠色噜噜狠狠狠7777奇米 | 国产精品久久精品三级 | 久久久久av无码免费网 | 亚洲综合另类小说色区 | 亚洲日本一区二区三区在线 | 亚洲中文字幕av在天堂 | 正在播放东北夫妻内射 | 国产色xx群视频射精 | 欧美变态另类xxxx | 激情内射亚州一区二区三区爱妻 | 少妇被粗大的猛进出69影院 | 无码人妻精品一区二区三区下载 | 一个人看的www免费视频在线观看 | 日韩成人一区二区三区在线观看 | 欧美日本精品一区二区三区 | 国语自产偷拍精品视频偷 | 色综合久久88色综合天天 | 欧美性猛交xxxx富婆 | 日本肉体xxxx裸交 | 曰韩少妇内射免费播放 | 99久久久国产精品无码免费 | 男女猛烈xx00免费视频试看 | 亚洲人交乣女bbw | 日本精品高清一区二区 | 人妻无码αv中文字幕久久琪琪布 | 欧美老熟妇乱xxxxx | а√资源新版在线天堂 | 午夜男女很黄的视频 | 亚洲欧美色中文字幕在线 | 性生交大片免费看l | 骚片av蜜桃精品一区 | www国产亚洲精品久久久日本 | 日本护士xxxxhd少妇 | 无码国内精品人妻少妇 | 人妻无码αv中文字幕久久琪琪布 | 亚洲精品成人av在线 | 亚洲综合另类小说色区 | 精品国产av色一区二区深夜久久 | 色婷婷久久一区二区三区麻豆 | 亚洲精品国产品国语在线观看 | 青草视频在线播放 | 成人欧美一区二区三区黑人 | 亚洲 欧美 激情 小说 另类 | 国产精品va在线观看无码 | 97久久超碰中文字幕 | 伊在人天堂亚洲香蕉精品区 | 午夜理论片yy44880影院 | 婷婷五月综合激情中文字幕 | 亚洲娇小与黑人巨大交 | 99久久99久久免费精品蜜桃 | 久青草影院在线观看国产 | 无码人妻少妇伦在线电影 | 99久久99久久免费精品蜜桃 | 曰本女人与公拘交酡免费视频 | 日本精品久久久久中文字幕 | 国产偷抇久久精品a片69 | 亚洲 欧美 激情 小说 另类 | 狂野欧美性猛交免费视频 | 精品国产精品久久一区免费式 | www成人国产高清内射 | 久久久久成人片免费观看蜜芽 | 久久99精品国产麻豆蜜芽 | 久久久国产精品无码免费专区 | 免费看男女做好爽好硬视频 | 丰满少妇弄高潮了www | 天堂久久天堂av色综合 | 老司机亚洲精品影院无码 | 99久久精品午夜一区二区 | 国产午夜福利亚洲第一 | aⅴ亚洲 日韩 色 图网站 播放 | 久久亚洲日韩精品一区二区三区 | 日本护士xxxxhd少妇 | 国产一精品一av一免费 | 粗大的内捧猛烈进出视频 | 永久黄网站色视频免费直播 | 国产亚洲精品久久久久久久 | 国产精品内射视频免费 | 欧美成人高清在线播放 | 国产97人人超碰caoprom | 国产高清av在线播放 | 亚洲国产av精品一区二区蜜芽 | 扒开双腿疯狂进出爽爽爽视频 | 久久精品人人做人人综合 | 鲁鲁鲁爽爽爽在线视频观看 | 少妇无码一区二区二三区 | 在线欧美精品一区二区三区 | 偷窥日本少妇撒尿chinese | 好男人www社区 | 樱花草在线播放免费中文 | 毛片内射-百度 | 日韩精品乱码av一区二区 | 久久亚洲精品成人无码 | 老熟妇仑乱视频一区二区 | 亚洲色大成网站www国产 | 国产一区二区三区影院 | 中文字幕无码av激情不卡 | 精品偷自拍另类在线观看 | 国产成人精品一区二区在线小狼 | 久久视频在线观看精品 | 婷婷色婷婷开心五月四房播播 | 夜夜躁日日躁狠狠久久av | 国内老熟妇对白xxxxhd | 日日噜噜噜噜夜夜爽亚洲精品 | 国产成人精品视频ⅴa片软件竹菊 | 日韩欧美中文字幕公布 | 亚洲日韩av一区二区三区中文 | 青青草原综合久久大伊人精品 | 欧美大屁股xxxxhd黑色 | 久久综合网欧美色妞网 | 樱花草在线社区www | 成人无码视频在线观看网站 | 人妻插b视频一区二区三区 | 无码人妻精品一区二区三区不卡 | 久久综合色之久久综合 | 久久精品国产一区二区三区肥胖 | 国产精品久久国产精品99 | 精品国产国产综合精品 | 正在播放东北夫妻内射 | 成人性做爰aaa片免费看不忠 | 欧美性黑人极品hd | 成人无码精品一区二区三区 | 国产真人无遮挡作爱免费视频 | 无码人妻黑人中文字幕 | 欧美老妇与禽交 | 乱人伦中文视频在线观看 | 2019午夜福利不卡片在线 | 一二三四在线观看免费视频 | 97精品国产97久久久久久免费 | 无码毛片视频一区二区本码 | 亚洲自偷自拍另类第1页 | 国产又爽又猛又粗的视频a片 | 国产成人综合美国十次 | 亚洲欧洲日本综合aⅴ在线 | 亚洲日韩乱码中文无码蜜桃臀网站 | 国产精品永久免费视频 | 久久久久久亚洲精品a片成人 | 亚洲人交乣女bbw | 国产97在线 | 亚洲 | 国产超碰人人爽人人做人人添 | 日本精品久久久久中文字幕 | 国产免费久久精品国产传媒 | 精品久久久中文字幕人妻 | 亚洲s码欧洲m码国产av | 国内揄拍国内精品人妻 | 国产香蕉尹人视频在线 | 无码人妻久久一区二区三区不卡 | 久久综合狠狠综合久久综合88 | 精品国产一区二区三区四区 | 国产精品久久久久7777 | 亚洲成av人片在线观看无码不卡 | 欧美精品在线观看 | 夫妻免费无码v看片 | 2020久久香蕉国产线看观看 | 日本一卡2卡3卡四卡精品网站 | 久久久久久久久蜜桃 | 永久免费精品精品永久-夜色 | 人妻少妇精品久久 | 扒开双腿疯狂进出爽爽爽视频 | 青草视频在线播放 | 国产香蕉尹人综合在线观看 | 欧美一区二区三区视频在线观看 | 国产97色在线 | 免 | 动漫av网站免费观看 | 色综合久久久无码中文字幕 | 欧美亚洲日韩国产人成在线播放 | 精品无码国产自产拍在线观看蜜 | 成人影院yy111111在线观看 | 人人澡人摸人人添 | 无码人妻出轨黑人中文字幕 | 欧洲精品码一区二区三区免费看 | 久久国产自偷自偷免费一区调 | 无套内谢的新婚少妇国语播放 | 在线看片无码永久免费视频 | 国产av人人夜夜澡人人爽麻豆 | 狂野欧美激情性xxxx | 久久www免费人成人片 | 中国大陆精品视频xxxx | 久久99精品国产麻豆 | 国产在线精品一区二区三区直播 | 中文字幕无线码免费人妻 | 亚洲国产精品无码久久久久高潮 | 中文字幕乱码亚洲无线三区 | а√天堂www在线天堂小说 | 国产日产欧产精品精品app | 久久久国产一区二区三区 | 亚洲成熟女人毛毛耸耸多 | 久久人人爽人人人人片 | 色欲久久久天天天综合网精品 | 激情五月综合色婷婷一区二区 | 国产精品嫩草久久久久 | 樱花草在线社区www | 国产精品无码一区二区桃花视频 | 国产精品99久久精品爆乳 | 精品国产麻豆免费人成网站 | 国产精品久久国产精品99 | 中文字幕+乱码+中文字幕一区 | 国产精品久久久久久亚洲毛片 | 亚洲一区二区三区含羞草 | 又粗又大又硬毛片免费看 | 亚洲小说图区综合在线 | 国产精品99久久精品爆乳 | 久久精品国产一区二区三区 | 狠狠噜狠狠狠狠丁香五月 | 国产精品无码一区二区桃花视频 | 在线 国产 欧美 亚洲 天堂 | 四虎国产精品一区二区 | 国产人妻精品午夜福利免费 | 一本无码人妻在中文字幕免费 | 亚洲欧洲日本无在线码 | 奇米影视888欧美在线观看 | 日韩精品无码免费一区二区三区 | 性欧美牲交xxxxx视频 | 学生妹亚洲一区二区 | 亚洲熟熟妇xxxx | 国产亲子乱弄免费视频 | 无遮挡国产高潮视频免费观看 | 国产97色在线 | 免 | 久久婷婷五月综合色国产香蕉 | 国产在线aaa片一区二区99 | 亚洲欧美日韩国产精品一区二区 | 中文字幕人妻无码一区二区三区 | 免费网站看v片在线18禁无码 | 99麻豆久久久国产精品免费 | 精品日本一区二区三区在线观看 | 欧美第一黄网免费网站 | 国产欧美熟妇另类久久久 | 99久久亚洲精品无码毛片 | 亚洲乱码日产精品bd | 97夜夜澡人人双人人人喊 | 两性色午夜免费视频 | 国产精品-区区久久久狼 | 99re在线播放 | 国产精品久久福利网站 | 在教室伦流澡到高潮hnp视频 | 日日夜夜撸啊撸 | 毛片内射-百度 | 永久免费观看国产裸体美女 | 熟女俱乐部五十路六十路av | 亚洲男女内射在线播放 | 色一情一乱一伦一区二区三欧美 | 国产免费久久久久久无码 | 精品国精品国产自在久国产87 | 国产亚洲精品久久久久久国模美 | 国产精品久久久久影院嫩草 | 一本久久a久久精品亚洲 | 国产人成高清在线视频99最全资源 | 99在线 | 亚洲 | 国精品人妻无码一区二区三区蜜柚 | 中文字幕无码av波多野吉衣 | 国产免费久久久久久无码 | 人妻aⅴ无码一区二区三区 | 女人被爽到呻吟gif动态图视看 | 少女韩国电视剧在线观看完整 | 久久久av男人的天堂 | 女人色极品影院 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 国产黄在线观看免费观看不卡 | 国产欧美精品一区二区三区 | 夜夜躁日日躁狠狠久久av | 荫蒂添的好舒服视频囗交 | 色情久久久av熟女人妻网站 | 宝宝好涨水快流出来免费视频 | 国产精品多人p群无码 | 玩弄中年熟妇正在播放 | 一区二区传媒有限公司 | 永久免费精品精品永久-夜色 | 日韩亚洲欧美精品综合 | 老熟妇仑乱视频一区二区 | 中国大陆精品视频xxxx | 亚洲精品久久久久久一区二区 | 国产区女主播在线观看 | 亚洲精品成a人在线观看 | 波多野结衣乳巨码无在线观看 | 大肉大捧一进一出好爽视频 | 300部国产真实乱 | 日韩欧美中文字幕公布 | 亚洲综合无码一区二区三区 | 久青草影院在线观看国产 | 中文字幕久久久久人妻 | 一本大道久久东京热无码av | 兔费看少妇性l交大片免费 | 少妇人妻大乳在线视频 | 丰满人妻精品国产99aⅴ | 两性色午夜免费视频 | 国产精品久久久久9999小说 | 久久这里只有精品视频9 | 99riav国产精品视频 | 欧美日韩视频无码一区二区三 | 欧美丰满熟妇xxxx性ppx人交 | 又大又硬又黄的免费视频 | 国产特级毛片aaaaaa高潮流水 | 漂亮人妻洗澡被公强 日日躁 | 精品国偷自产在线视频 | 无码国产色欲xxxxx视频 | 日本熟妇浓毛 | 人妻少妇精品无码专区二区 | 精品欧洲av无码一区二区三区 | 日本一区二区更新不卡 | 久久综合九色综合欧美狠狠 | 欧美第一黄网免费网站 | 熟妇人妻无码xxx视频 | 奇米影视7777久久精品人人爽 | 久激情内射婷内射蜜桃人妖 | 丁香花在线影院观看在线播放 | 久久人人爽人人爽人人片av高清 | 亚洲色无码一区二区三区 | 免费人成在线观看网站 | 乱中年女人伦av三区 | 国产熟妇高潮叫床视频播放 | 亚洲精品国产a久久久久久 | 国产69精品久久久久app下载 | 久久国产劲爆∧v内射 | 成人影院yy111111在线观看 | 蜜桃av抽搐高潮一区二区 | 国产内射老熟女aaaa | 性色av无码免费一区二区三区 | 精品无码av一区二区三区 | 欧美丰满少妇xxxx性 | 内射老妇bbwx0c0ck | 熟妇女人妻丰满少妇中文字幕 | 麻豆成人精品国产免费 | 无码福利日韩神码福利片 | av在线亚洲欧洲日产一区二区 | 精品国产精品久久一区免费式 | 国产精品办公室沙发 | 国产精品高潮呻吟av久久4虎 | 大乳丰满人妻中文字幕日本 | 一本色道久久综合亚洲精品不卡 | 九九综合va免费看 | 成人欧美一区二区三区黑人免费 | 亚洲 激情 小说 另类 欧美 | 亚洲人成影院在线无码按摩店 | 亚洲成a人片在线观看无码3d | 白嫩日本少妇做爰 | 久久久久se色偷偷亚洲精品av | 日日摸夜夜摸狠狠摸婷婷 | 成在人线av无码免费 | 青草青草久热国产精品 | 国产97人人超碰caoprom | 欧美阿v高清资源不卡在线播放 | 亚洲色www成人永久网址 | 精品国产一区二区三区av 性色 | 老熟妇乱子伦牲交视频 | 国产精品无码永久免费888 | 夜精品a片一区二区三区无码白浆 | 亚洲伊人久久精品影院 | 国产av无码专区亚洲a∨毛片 | 亚洲无人区一区二区三区 | 亚洲色在线无码国产精品不卡 | 久久99精品久久久久婷婷 | 1000部夫妻午夜免费 | 国内综合精品午夜久久资源 | 成人无码精品一区二区三区 | 亚洲春色在线视频 | 色偷偷人人澡人人爽人人模 | 久久精品国产亚洲精品 | 女人和拘做爰正片视频 | 久久人人爽人人人人片 | 日本护士毛茸茸高潮 | 国产精品美女久久久久av爽李琼 | 国产激情无码一区二区 | 精品国产一区二区三区四区在线看 | 色综合久久久久综合一本到桃花网 | 亚洲中文字幕久久无码 | 亚洲一区二区三区国产精华液 | 少妇性l交大片欧洲热妇乱xxx | 夜夜躁日日躁狠狠久久av | 亚洲成a人片在线观看无码 | 成人性做爰aaa片免费看 | 亚洲人成人无码网www国产 | 精品久久久久久亚洲精品 | 国产色视频一区二区三区 | 亚洲中文字幕无码一久久区 | 精品无码国产一区二区三区av | 蜜桃视频插满18在线观看 | av无码不卡在线观看免费 | 亚洲国产精品久久久天堂 | 欧美精品在线观看 | 亚洲精品一区国产 | 亚洲色偷偷偷综合网 | 中文字幕乱码亚洲无线三区 | 亚洲爆乳精品无码一区二区三区 | 性色av无码免费一区二区三区 | 欧美丰满熟妇xxxx性ppx人交 | 国产免费无码一区二区视频 | 精品国产青草久久久久福利 | 少妇无码一区二区二三区 | 无码午夜成人1000部免费视频 | 东北女人啪啪对白 | 亚洲阿v天堂在线 | 99国产精品白浆在线观看免费 | 学生妹亚洲一区二区 | 国产亚洲精品久久久久久久 | 久激情内射婷内射蜜桃人妖 | 成人片黄网站色大片免费观看 | 国产真实伦对白全集 | 亚洲天堂2017无码中文 | 国内精品久久毛片一区二区 | a在线亚洲男人的天堂 | 夜夜影院未满十八勿进 | 午夜嘿嘿嘿影院 | 欧美阿v高清资源不卡在线播放 | 亚洲成a人一区二区三区 | 亚洲精品中文字幕久久久久 | 天天拍夜夜添久久精品大 | 亚洲日韩精品欧美一区二区 | 性欧美videos高清精品 | 精品国产成人一区二区三区 | 亚洲aⅴ无码成人网站国产app | 国产九九九九九九九a片 | 曰本女人与公拘交酡免费视频 | 国产精品久久久久久亚洲影视内衣 | 免费观看又污又黄的网站 | 蜜臀aⅴ国产精品久久久国产老师 | 国产做国产爱免费视频 | 国产综合色产在线精品 | 奇米影视888欧美在线观看 | 乱人伦人妻中文字幕无码 | 亚洲欧美色中文字幕在线 | 精品国产av色一区二区深夜久久 | 日本高清一区免费中文视频 | 大地资源网第二页免费观看 | 欧美日本免费一区二区三区 | 亚洲成av人片在线观看无码不卡 | 内射欧美老妇wbb | 男女猛烈xx00免费视频试看 | 亚洲中文无码av永久不收费 | 少妇久久久久久人妻无码 | 亚洲综合伊人久久大杳蕉 | 精品厕所偷拍各类美女tp嘘嘘 | 久久久久久九九精品久 | 国产一区二区三区日韩精品 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 男女下面进入的视频免费午夜 | 最新国产麻豆aⅴ精品无码 | 久久亚洲中文字幕精品一区 | 欧美 亚洲 国产 另类 | 永久免费精品精品永久-夜色 | 国产内射爽爽大片视频社区在线 | 久久国产精品二国产精品 | 亚洲国产精品一区二区美利坚 | 九一九色国产 | 亚洲中文字幕在线观看 | 亚洲人成网站在线播放942 | 亚洲人成影院在线无码按摩店 | 亚洲日韩精品欧美一区二区 | 欧美黑人性暴力猛交喷水 | 性做久久久久久久久 | 国产99久久精品一区二区 | 国语精品一区二区三区 | 亚洲日韩中文字幕在线播放 | 日本高清一区免费中文视频 | 国产精品无码永久免费888 | 免费国产成人高清在线观看网站 | 亚洲色无码一区二区三区 | 精品久久久无码人妻字幂 | 精品乱子伦一区二区三区 | 欧美精品无码一区二区三区 | 久久久久国色av免费观看性色 | 国产明星裸体无码xxxx视频 | 福利一区二区三区视频在线观看 | 免费国产黄网站在线观看 | 亚洲成av人片在线观看无码不卡 | 97精品国产97久久久久久免费 | 装睡被陌生人摸出水好爽 | 欧美国产亚洲日韩在线二区 | 日本熟妇乱子伦xxxx | 国产精品手机免费 | 人妻互换免费中文字幕 | 77777熟女视频在线观看 а天堂中文在线官网 | 一本色道婷婷久久欧美 | 免费看少妇作爱视频 | 少妇性l交大片欧洲热妇乱xxx | 精品国产aⅴ无码一区二区 | 在线播放免费人成毛片乱码 | 性色欲网站人妻丰满中文久久不卡 | 国产亚洲精品久久久久久久久动漫 | 日本精品久久久久中文字幕 | 国产乡下妇女做爰 | 波多野结衣一区二区三区av免费 | 久久综合香蕉国产蜜臀av | 55夜色66夜色国产精品视频 | 99久久久无码国产精品免费 | 国产亚洲精品精品国产亚洲综合 | av无码久久久久不卡免费网站 | 国产三级久久久精品麻豆三级 | 国产口爆吞精在线视频 | 无码国模国产在线观看 | 女高中生第一次破苞av | av人摸人人人澡人人超碰下载 | 最新版天堂资源中文官网 | 亚洲综合无码一区二区三区 | 综合激情五月综合激情五月激情1 | 在线精品亚洲一区二区 | 久久久中文久久久无码 | 久久精品女人天堂av免费观看 | 一本久道久久综合婷婷五月 | 免费视频欧美无人区码 | 强辱丰满人妻hd中文字幕 | 亚洲码国产精品高潮在线 | 狠狠噜狠狠狠狠丁香五月 | 国产一区二区不卡老阿姨 | 久久精品国产99精品亚洲 | 人妻插b视频一区二区三区 | 久久久久99精品成人片 | 欧美自拍另类欧美综合图片区 | 无码吃奶揉捏奶头高潮视频 | 国内精品久久久久久中文字幕 | 久久久久久av无码免费看大片 | 国产精品久久久午夜夜伦鲁鲁 | 国产欧美熟妇另类久久久 | 99国产欧美久久久精品 | 牲欲强的熟妇农村老妇女视频 | 色诱久久久久综合网ywww | 久久久婷婷五月亚洲97号色 | 欧美人与禽zoz0性伦交 | 久久 国产 尿 小便 嘘嘘 | 亚洲人成网站免费播放 | 大肉大捧一进一出视频出来呀 | 午夜理论片yy44880影院 | 亚洲乱码国产乱码精品精 | 99久久婷婷国产综合精品青草免费 | 超碰97人人做人人爱少妇 | 精品乱子伦一区二区三区 | 夜先锋av资源网站 | 国产黄在线观看免费观看不卡 | 最新国产乱人伦偷精品免费网站 | 中文精品久久久久人妻不卡 | 天堂亚洲免费视频 | 欧美日韩色另类综合 | 色欲久久久天天天综合网精品 | 国产免费久久精品国产传媒 | 欧美激情一区二区三区成人 | 日本在线高清不卡免费播放 | 久久久成人毛片无码 | 久久五月精品中文字幕 | 中文字幕精品av一区二区五区 | 亚洲日韩av一区二区三区四区 | 伊人久久大香线蕉亚洲 | 在线成人www免费观看视频 | 99久久久无码国产aaa精品 | 熟女体下毛毛黑森林 | 国产特级毛片aaaaaaa高清 | 成人试看120秒体验区 | 亚洲成a人片在线观看无码3d | 欧洲欧美人成视频在线 | 一本一道久久综合久久 | 福利一区二区三区视频在线观看 | 天堂亚洲免费视频 | 狠狠躁日日躁夜夜躁2020 | 国产精品香蕉在线观看 | 精品国产av色一区二区深夜久久 | 日本一卡二卡不卡视频查询 | 亚洲乱亚洲乱妇50p | 在线播放免费人成毛片乱码 | 久久国产劲爆∧v内射 | 一本色道久久综合亚洲精品不卡 | 日韩人妻无码中文字幕视频 | 久久久久亚洲精品中文字幕 | 麻豆国产丝袜白领秘书在线观看 | 亚洲狠狠婷婷综合久久 |