日韩精品一区二区三区在线视频放-无码中文字幕V?一区二区-成年片免费观看视频-国内少妇人妻丰满av-国产精品中文字幕免费观看-亚洲成人久久一区二区三区-国内少妇偷人精品视频无缓冲-一区二区国产精品日本一区二区三区在线网

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運營的一線實戰(zhàn)洞察。

四向鏈表從創(chuàng)建到遍歷:指針維護與DFS/BFS實戰(zhàn)

四向鏈表從創(chuàng)建到遍歷:指針維護與DFS/BFS實戰(zhàn) 1. 四向鏈表到底是個什么東西先把概念說清楚。四向鏈表英文一般叫 Quadruple Linked List 或者 Four-way Linked List本質(zhì)上是一種每個節(jié)點持有四個指針的鏈?zhǔn)浇Y(jié)構(gòu)。最常見的定義是每個節(jié)點同時擁有上、下、左、右四個方向的指針分別指向相鄰的四個節(jié)點。它和雙向鏈表prev/next最大的區(qū)別在于雙向鏈表只在一維上串聯(lián)而四向鏈表在二維平面上建立了連接關(guān)系。你可以把它想象成一張稀疏矩陣或者網(wǎng)格地圖。每個節(jié)點就是地圖上的一個格子四個指針就是通往上下左右四個鄰居的路。這種結(jié)構(gòu)在需要表達(dá)二維鄰接關(guān)系的場景里非常有用比如棋盤類游戲的狀態(tài)表示、圖像處理中的像素鄰域關(guān)系、迷宮尋路算法中的節(jié)點建模以及某些稀疏矩陣的存儲方案。那為什么不用二維數(shù)組呢因為二維數(shù)組是稠密的不管你有沒有數(shù)據(jù)空間都得先分配好。而四向鏈表是稀疏的只有實際存在的節(jié)點才會占用內(nèi)存節(jié)點之間的連接通過指針動態(tài)建立。當(dāng)你的二維數(shù)據(jù)非常稀疏、或者節(jié)點數(shù)量動態(tài)變化的時候四向鏈表的優(yōu)勢就體現(xiàn)出來了。不過話說回來四向鏈表也有它自己的麻煩。指針多了維護成本就高。插入一個節(jié)點你可能需要同時修改四個方向的鄰居指針刪除一個節(jié)點同樣要處理四個方向的斷鏈和重連。稍有不慎就會出現(xiàn)懸空指針或者環(huán)形引用。這也是為什么很多人在實現(xiàn)四向鏈表的時候?qū)懼鴮懼蛠y了。提示四向鏈表的核心難點不在創(chuàng)建而在維護。創(chuàng)建只是搭骨架維護才是真正考驗?zāi)銓χ羔樌斫馍疃鹊牡胤?。我見過不少初學(xué)者一上來就急著寫遍歷代碼結(jié)果鏈表本身都沒建對遍歷出來的結(jié)果自然一塌糊涂。所以這篇文章我會從創(chuàng)建開始一步步把四向鏈表的完整實現(xiàn)講透包括打印預(yù)覽、遍歷策略以及最關(guān)鍵的——從任意節(jié)點出發(fā)遍歷整個鏈表且不重復(fù)。2. 節(jié)點結(jié)構(gòu)設(shè)計與創(chuàng)建邏輯2.1 四個指針的命名與語義約定在動手寫代碼之前必須先約定好四個指針的命名和語義。這不是小事命名混亂是后期調(diào)試噩夢的根源。我推薦用 up、down、left、right 這四個名字語義直觀不容易搞混。typedef struct QuadNode { int data; // 節(jié)點存儲的數(shù)據(jù) struct QuadNode* up; // 上鄰居 struct QuadNode* down; // 下鄰居 struct QuadNode* left; // 左鄰居 struct QuadNode* right; // 右鄰居 } QuadNode;如果你用的是 Java 或者 Python思路一樣只是把指針換成引用而已。用泛型的話把 int 換成泛型參數(shù) T 就行。public class QuadNodeT { T data; QuadNodeT up; QuadNodeT down; QuadNodeT left; QuadNodeT right; public QuadNode(T data) { this.data data; this.up null; this.down null; this.left null; this.right null; } }這里有一個設(shè)計決策需要解釋為什么用四個獨立的指針而不是用一個指針數(shù)組QuadNode* neighbors[4]兩種方式都能工作但獨立指針的可讀性更好代碼里寫node-up比寫node-neighbors[0]要清晰得多。當(dāng)然如果你需要循環(huán)處理四個方向數(shù)組會更方便。我的建議是如果四個方向的邏輯差異較大用獨立指針如果需要統(tǒng)一遍歷四個方向用數(shù)組加枚舉索引。2.2 從網(wǎng)格構(gòu)建四向鏈表創(chuàng)建四向鏈表最直觀的方式是從一個二維網(wǎng)格開始。假設(shè)我們有一個 m 行 n 列的網(wǎng)格每個格子對應(yīng)一個節(jié)點然后按行列關(guān)系把指針連起來。QuadNode* createGrid(int rows, int cols) { // 先分配所有節(jié)點 QuadNode** grid (QuadNode**)malloc(rows * sizeof(QuadNode*)); for (int i 0; i rows; i) { grid[i] (QuadNode*)malloc(cols * sizeof(QuadNode)); for (int j 0; j cols; j) { grid[i][j].data i * cols j; grid[i][j].up NULL; grid[i][j].down NULL; grid[i][j].left NULL; grid[i][j].right NULL; } } // 建立四向連接 for (int i 0; i rows; i) { for (int j 0; j cols; j) { if (i 0) grid[i][j].up grid[i-1][j]; if (i rows - 1) grid[i][j].down grid[i1][j]; if (j 0) grid[i][j].left grid[i][j-1]; if (j cols - 1) grid[i][j].right grid[i][j1]; } } return grid[0][0]; // 返回左上角節(jié)點作為入口 }這段代碼的邏輯很直接第一輪循環(huán)分配內(nèi)存并初始化第二輪循環(huán)建立連接。注意邊界處理——第一行沒有上鄰居最后一行沒有下鄰居第一列沒有左鄰居最后一列沒有右鄰居。這些邊界節(jié)點的對應(yīng)指針保持為 NULL。但這里有個坑上面這種寫法是一次性分配一整塊連續(xù)內(nèi)存grid[i]和grid[i1]之間的地址是連續(xù)的。這在某些場景下沒問題但如果你需要動態(tài)增刪節(jié)點連續(xù)內(nèi)存就不合適了。動態(tài)場景下每個節(jié)點應(yīng)該獨立 malloc。QuadNode* createNode(int data) { QuadNode* node (QuadNode*)malloc(sizeof(QuadNode)); node-data data; node-up node-down node-left node-right NULL; return node; }然后在需要的時候逐個創(chuàng)建并手動連接。這種方式更靈活但維護成本也更高因為你需要自己追蹤所有已創(chuàng)建的節(jié)點否則容易內(nèi)存泄漏。2.3 動態(tài)插入節(jié)點時的指針維護往已有的四向鏈表里插入一個新節(jié)點是最容易出錯的操作。假設(shè)你要在節(jié)點 A 的右邊插入新節(jié)點 B你需要做四件事B 的 left 指向 AB 的 right 指向 A 原來的 right記為 CA 的 right 指向 B如果 C 不為 NULLC 的 left 指向 Bvoid insertRight(QuadNode* a, QuadNode* b) { if (a NULL || b NULL) return; QuadNode* c a-right; b-left a; b-right c; a-right b; if (c ! NULL) { c-left b; } }看起來簡單但實際項目中插入操作往往涉及上下方向的聯(lián)動。比如你在一行中間插入了一個節(jié)點那這個節(jié)點上方的節(jié)點和下方的節(jié)點是否也需要對應(yīng)調(diào)整這取決于你的業(yè)務(wù)邏輯。如果四向鏈表表示的是一個規(guī)則的網(wǎng)格那插入一個節(jié)點意味著整行或整列都要調(diào)整這時候就需要更復(fù)雜的批量操作。注意每次插入或刪除操作后建議立即做一次完整性校驗——檢查每個節(jié)點的四個指針是否自洽。比如node-right-left應(yīng)該等于nodenode-down-up應(yīng)該等于node。這個校驗?zāi)軒湍惚M早發(fā)現(xiàn)指針錯誤。3. 打印預(yù)覽把鏈表可視化出來3.1 為什么打印預(yù)覽比你想的重要很多人覺得打印鏈表就是調(diào)試用的臨時手段不值得花時間。但我的經(jīng)驗恰恰相反一個設(shè)計良好的打印函數(shù)能幫你節(jié)省大量調(diào)試時間。四向鏈表的結(jié)構(gòu)比單鏈表復(fù)雜得多光靠腦子想或者畫圖很容易出錯有一個能隨時輸出當(dāng)前鏈表狀態(tài)的函數(shù)價值極高。打印四向鏈表的核心思路是按行遍歷每行從左到右輸出節(jié)點數(shù)據(jù)行與行之間用換行分隔。但問題是四向鏈表不一定是從左上角開始的規(guī)則網(wǎng)格它可能是一個不規(guī)則的形狀。所以打印函數(shù)需要處理如何確定遍歷的起點和范圍這個問題。3.2 基于左上角起點的逐行打印最簡單的情況是你知道鏈表的最左上角節(jié)點即沒有 up 和 left 的節(jié)點從這個節(jié)點出發(fā)先一路向下走到最底部再逐行向右打印。void printGrid(QuadNode* topLeft) { if (topLeft NULL) return; // 先找到最左上角的節(jié)點 QuadNode* rowStart topLeft; while (rowStart-up ! NULL) rowStart rowStart-up; while (rowStart-left ! NULL) rowStart rowStart-left; // 逐行打印 QuadNode* rowNode rowStart; while (rowNode ! NULL) { QuadNode* colNode rowNode; while (colNode ! NULL) { printf(%4d, colNode-data); colNode colNode-right; } printf(\n); rowNode rowNode-down; } }這段代碼的邏輯是先定位到最左上角然后外層循環(huán)沿 down 方向逐行移動內(nèi)層循環(huán)沿 right 方向逐個打印。輸出效果就是一個整齊的矩陣。但這里有個隱患如果鏈表不是規(guī)則網(wǎng)格某一行的節(jié)點數(shù)和其他行不一樣打印出來就會參差不齊。對于不規(guī)則鏈表你需要更靈活的打印策略比如按坐標(biāo)定位輸出或者用遞歸方式逐層打印。3.3 處理不規(guī)則形狀的打印方案不規(guī)則四向鏈表的打印我推薦用遞歸加訪問標(biāo)記的方式。核心思路是從任意一個節(jié)點出發(fā)遞歸訪問它的四個鄰居同時記錄每個節(jié)點的深度和橫向位置最后按位置排序輸出。void printIrregular(QuadNode* node, int row, int col, int* minRow, int* maxRow, int* minCol, int* maxCol, HashMap* visited) { if (node NULL) return; if (contains(visited, node)) return; add(visited, node); // 更新邊界 if (row *minRow) *minRow row; if (row *maxRow) *maxRow row; if (col *minCol) *minCol col; if (col *maxCol) *maxCol col; // 記錄節(jié)點位置 recordPosition(node, row, col); // 遞歸四個方向 printIrregular(node-up, row - 1, col, minRow, maxRow, minCol, maxCol, visited); printIrregular(node-down, row 1, col, minRow, maxRow, minCol, maxCol, visited); printIrregular(node-left, row, col - 1, minRow, maxRow, minCol, maxCol, visited); printIrregular(node-right, row, col 1, minRow, maxRow, minCol, maxCol, visited); }這個方案的好處是通用性強不管鏈表是什么形狀都能處理。代價是需要額外的空間來記錄訪問狀態(tài)和節(jié)點位置。在實際項目中如果鏈表規(guī)模不大幾百個節(jié)點以內(nèi)這個方案完全夠用。4. 遍歷策略從任意節(jié)點出發(fā)走遍全圖4.1 四向鏈表遍歷的本質(zhì)是圖遍歷這是整篇文章最核心的部分。四向鏈表從遍歷的角度看本質(zhì)上就是一個無向圖——每個節(jié)點最多有四個鄰居節(jié)點之間的連接是雙向的。所以遍歷四向鏈表本質(zhì)上就是圖的遍歷問題。既然是圖遍歷那就繞不開兩個經(jīng)典算法深度優(yōu)先搜索DFS和廣度優(yōu)先搜索BFS。這兩個算法都能實現(xiàn)從任意節(jié)點出發(fā)遍歷整個鏈表且不重復(fù)的目標(biāo)區(qū)別在于訪問順序不同。DFS 用棧遞歸或顯式棧實現(xiàn)沿著一個方向一直走到底再回溯。BFS 用隊列實現(xiàn)先訪問所有直接鄰居再訪問鄰居的鄰居一層層往外擴展。那選哪個取決于你的需求。如果你需要按距離層次處理節(jié)點用 BFS如果你只是需要遍歷所有節(jié)點DFS 更簡潔。在四向鏈表的場景下DFS 的遞歸寫法最直觀但如果鏈表很深比如幾萬個節(jié)點遞歸可能導(dǎo)致棧溢出這時候需要改成顯式棧的迭代寫法。4.2 用訪問標(biāo)記避免重復(fù)遍歷不管用 DFS 還是 BFS不重復(fù)的關(guān)鍵都在于訪問標(biāo)記。每訪問一個節(jié)點就把它標(biāo)記為已訪問后續(xù)再遇到這個節(jié)點時直接跳過。標(biāo)記的方式有幾種哈希表用節(jié)點的內(nèi)存地址作為 key通用性最強但需要額外的哈希表空間。節(jié)點內(nèi)置標(biāo)記位在節(jié)點結(jié)構(gòu)里加一個visited字段最省事但會污染節(jié)點結(jié)構(gòu)而且遍歷完后需要重置。外部數(shù)組如果節(jié)點是連續(xù)分配的可以用索引來標(biāo)記效率最高但只適用于特定場景。我一般推薦用哈希表因為最通用不依賴節(jié)點的內(nèi)存布局。在 C 語言里可以用一個簡單的開放尋址哈希表在 Java 里直接用 HashSet在 Python 里用 set。// 用哈希集合記錄已訪問節(jié)點 typedef struct { QuadNode** buckets; int capacity; int size; } HashSet; int hashNode(QuadNode* node, int capacity) { return ((unsigned long)node / sizeof(QuadNode)) % capacity; } int contains(HashSet* set, QuadNode* node) { int idx hashNode(node, set-capacity); while (set-buckets[idx] ! NULL) { if (set-buckets[idx] node) return 1; idx (idx 1) % set-capacity; } return 0; } void add(HashSet* set, QuadNode* node) { int idx hashNode(node, set-capacity); while (set-buckets[idx] ! NULL) { if (set-buckets[idx] node) return; idx (idx 1) % set-capacity; } set-buckets[idx] node; set-size; }4.3 DFS 實現(xiàn)遞歸與迭代兩種寫法先看遞歸版本最簡潔void dfsTraverse(QuadNode* node, HashSet* visited, void (*visit)(QuadNode*)) { if (node NULL) return; if (contains(visited, node)) return; add(visited, node); visit(node); dfsTraverse(node-up, visited, visit); dfsTraverse(node-down, visited, visit); dfsTraverse(node-left, visited, visit); dfsTraverse(node-right, visited, visit); }四行遞歸調(diào)用對應(yīng)四個方向。邏輯清晰代碼短。但遞歸深度等于最長路徑長度如果鏈表是一條長鏈比如一萬個節(jié)點排成一條線遞歸深度就是一萬很可能棧溢出。迭代版本用顯式棧void dfsTraverseIterative(QuadNode* start, HashSet* visited, void (*visit)(QuadNode*)) { if (start NULL) return; QuadNode** stack (QuadNode**)malloc(10000 * sizeof(QuadNode*)); int top 0; stack[top] start; while (top 0) { QuadNode* node stack[--top]; if (node NULL || contains(visited, node)) continue; add(visited, node); visit(node); // 四個方向入棧順序無所謂 if (node-up) stack[top] node-up; if (node-down) stack[top] node-down; if (node-left) stack[top] node-left; if (node-right) stack[top] node-right; } free(stack); }迭代版本不會棧溢出但需要手動管理??臻g。實際項目中如果鏈表規(guī)??煽剡f歸版本更省事如果規(guī)模不確定用迭代版本更安全。4.4 BFS 實現(xiàn)與層序輸出BFS 用隊列代碼結(jié)構(gòu)類似void bfsTraverse(QuadNode* start, HashSet* visited, void (*visit)(QuadNode*)) { if (start NULL) return; QuadNode** queue (QuadNode**)malloc(10000 * sizeof(QuadNode*)); int front 0, rear 0; queue[rear] start; add(visited, start); while (front rear) { QuadNode* node queue[front]; visit(node); QuadNode* neighbors[4] {node-up, node-down, node-left, node-right}; for (int i 0; i 4; i) { if (neighbors[i] ! NULL !contains(visited, neighbors[i])) { add(visited, neighbors[i]); queue[rear] neighbors[i]; } } } free(queue); }BFS 的一個天然優(yōu)勢是它按距離層次訪問節(jié)點。從起點出發(fā)距離為 1 的節(jié)點先訪問然后是距離為 2 的以此類推。如果你需要按層輸出類似樹的層序遍歷BFS 是天然的選擇。void bfsLevelOrder(QuadNode* start, HashSet* visited) { if (start NULL) return; QuadNode** queue (QuadNode**)malloc(10000 * sizeof(QuadNode*)); int front 0, rear 0; queue[rear] start; add(visited, start); int level 0; while (front rear) { int levelSize rear - front; printf(Level %d: , level); for (int i 0; i levelSize; i) { QuadNode* node queue[front]; printf(%d , node-data); QuadNode* neighbors[4] {node-up, node-down, node-left, node-right}; for (int j 0; j 4; j) { if (neighbors[j] ! NULL !contains(visited, neighbors[j])) { add(visited, neighbors[j]); queue[rear] neighbors[j]; } } } printf(\n); level; } free(queue); }這段代碼在標(biāo)準(zhǔn) BFS 的基礎(chǔ)上增加了層的概念。每次處理完當(dāng)前隊列中的所有節(jié)點即當(dāng)前層的所有節(jié)點再進(jìn)入下一層。輸出效果就是按距離分層的。5. 從任意節(jié)點出發(fā)的完整遍歷實戰(zhàn)5.1 為什么任意節(jié)點出發(fā)是個真需求在實際項目中你往往不能假設(shè)自己總是從左上角或者頭節(jié)點開始操作。比如在一個棋盤游戲里玩家可能點擊了棋盤中間的某個格子你需要從這個格子出發(fā)找到所有與它連通的區(qū)域。又比如在圖像處理中你從某個像素點開始做區(qū)域生長需要遍歷所有相鄰的相似像素。這些場景的共同點是起點是動態(tài)的不固定。所以遍歷算法必須支持從任意節(jié)點出發(fā)。好消息是DFS 和 BFS 天然支持任意起點——你只需要把起點傳進(jìn)去就行。真正需要注意的是從任意節(jié)點出發(fā)時如何確保遍歷到的是整個鏈表而不是鏈表的一部分。這里有一個前提條件四向鏈表必須是連通的。如果鏈表本身不連通存在孤立的子圖那從任意節(jié)點出發(fā)只能遍歷到該節(jié)點所在的連通分量無法到達(dá)其他分量。這是圖論的基本結(jié)論不是算法能解決的問題。提示如果你的四向鏈表可能不連通那遍歷整個鏈表這個需求本身就需要重新定義。你需要在遍歷完一個連通分量后找到未訪問的節(jié)點從那里開始新一輪遍歷直到所有節(jié)點都被訪問。5.2 完整代碼從任意節(jié)點出發(fā)的全遍歷下面是一個完整的實現(xiàn)包含從任意節(jié)點出發(fā)、遍歷所有連通分量、不重復(fù)訪問所有節(jié)點的邏輯void traverseAll(QuadNode* anyNode, HashSet* visited, void (*visit)(QuadNode*)) { // 第一步從給定節(jié)點出發(fā)遍歷其所在的連通分量 dfsTraverseIterative(anyNode, visited, visit); // 第二步如果鏈表不連通需要找到未訪問的節(jié)點繼續(xù)遍歷 // 這一步需要你有一個所有節(jié)點的列表或者能夠從某個已知節(jié)點 // 遍歷到所有節(jié)點。如果鏈表是連通的這一步可以省略。 }如果鏈表是連通的大多數(shù)四向鏈表場景都是連通的那上面的第一步就夠了。從任意節(jié)點出發(fā)DFS 或 BFS 會自動走遍所有節(jié)點。讓我用一個完整的例子來演示。假設(shè)我們有一個 3x4 的網(wǎng)格從中間的節(jié)點 (1,1) 出發(fā)遍歷int main() { // 創(chuàng)建 3x4 網(wǎng)格 QuadNode* topLeft createGrid(3, 4); // 找到中間的節(jié)點 (1,1) QuadNode* start topLeft; for (int i 0; i 1; i) start start-down; for (int j 0; j 1; j) start start-right; printf(Start from node: %d\n, start-data); // 初始化訪問集合 HashSet* visited createHashSet(100); // 從中間節(jié)點出發(fā)遍歷 printf(DFS traversal: ); dfsTraverseIterative(start, visited, printNode); printf(\n); // 重置訪問集合用 BFS 再遍歷一次 clearHashSet(visited); printf(BFS traversal: ); bfsTraverse(start, visited, printNode); printf(\n); return 0; }輸出結(jié)果會顯示從節(jié)點 5即 (1,1) 位置出發(fā)訪問了所有 12 個節(jié)點且每個節(jié)點只訪問一次。5.3 遍歷順序的差異與選擇依據(jù)DFS 和 BFS 的輸出順序差異很大。對于上面的 3x4 網(wǎng)格從 (1,1) 出發(fā)DFS 可能會輸出5, 1, 0, 4, 8, 9, 10, 11, 7, 6, 2, 3取決于四個方向的入棧順序BFS 可能會輸出5, 1, 4, 6, 9, 0, 2, 8, 10, 3, 7, 11按距離層次兩種順序都是正確的只是訪問次序不同。選擇哪個取決于你的業(yè)務(wù)需求需求場景推薦算法原因判斷連通性DFS只要能走通就行DFS 代碼更簡潔按距離處理BFSBFS 天然按距離分層尋找最短路徑BFSBFS 第一次到達(dá)目標(biāo)時就是最短路徑拓?fù)渑判蝾愋枨驞FSDFS 的后序遍歷有拓?fù)湫再|(zhì)內(nèi)存受限D(zhuǎn)FSDFS 棧深度通常小于 BFS 隊列寬度避免深遞歸BFSBFS 用隊列不受遞歸深度限制5.4 性能分析與常見優(yōu)化四向鏈表遍歷的時間復(fù)雜度是 O(V E)其中 V 是節(jié)點數(shù)E 是邊數(shù)。對于四向鏈表每個節(jié)點最多有 4 條邊所以 E ≤ 4V總時間復(fù)雜度是 O(V)。這是最優(yōu)的因為每個節(jié)點至少要被訪問一次。空間復(fù)雜度取決于算法DFS 遞歸O(V) ??臻g最壞情況DFS 迭代O(V) 顯式??臻gBFSO(V) 隊列空間訪問標(biāo)記O(V) 哈希表空間優(yōu)化的方向主要有兩個第一減少哈希表開銷。如果節(jié)點是連續(xù)分配的可以用節(jié)點索引代替指針哈希。比如createGrid分配的節(jié)點是連續(xù)的可以用(node - base) / sizeof(QuadNode)作為索引用一個 bit 數(shù)組來標(biāo)記訪問狀態(tài)空間占用從 O(V) 個指針降到 O(V/8) 個字節(jié)。第二提前終止。如果你只需要找到某個特定節(jié)點不需要遍歷全部可以在訪問到目標(biāo)節(jié)點時立即返回。DFS 和 BFS 都支持這種優(yōu)化。int dfsSearch(QuadNode* node, HashSet* visited, int target) { if (node NULL) return 0; if (contains(visited, node)) return 0; add(visited, node); if (node-data target) return 1; // 找到了立即返回 if (dfsSearch(node-up, visited, target)) return 1; if (dfsSearch(node-down, visited, target)) return 1; if (dfsSearch(node-left, visited, target)) return 1; if (dfsSearch(node-right, visited, target)) return 1; return 0; }這種提前終止在搜索場景下能大幅減少訪問節(jié)點數(shù)平均情況下可能只需要訪問一小部分節(jié)點就能找到目標(biāo)。6. 踩過的坑與實戰(zhàn)經(jīng)驗6.1 指針未初始化導(dǎo)致的隨機崩潰這是最常見的坑。malloc分配的內(nèi)存不會自動清零如果你忘了把四個指針初始化為 NULL它們就是隨機值。后續(xù)遍歷時訪問這些隨機指針輕則讀到垃圾數(shù)據(jù)重則直接段錯誤。我自己的習(xí)慣是每次malloc之后立即用memset清零或者用calloc代替malloc。QuadNode* node (QuadNode*)calloc(1, sizeof(QuadNode)); // calloc 會自動把內(nèi)存清零四個指針都是 NULL這個習(xí)慣能幫你避免大量低級錯誤。多花的那一點點性能和調(diào)試崩潰花的時間比起來完全不值一提。6.2 環(huán)形引用導(dǎo)致的無限遞歸四向鏈表的指針是雙向的A 的 right 指向 BB 的 left 指向 A。如果你在遍歷時忘了加訪問標(biāo)記或者訪問標(biāo)記的邏輯有 bug就會在 A 和 B 之間無限循環(huán)。更隱蔽的情況是訪問標(biāo)記加在了錯誤的位置。比如你在遞歸調(diào)用之后才標(biāo)記那在遞歸調(diào)用之前就已經(jīng)重復(fù)訪問了。// 錯誤寫法標(biāo)記太晚 void dfsWrong(QuadNode* node, HashSet* visited) { if (node NULL) return; if (contains(visited, node)) return; dfsWrong(node-up, visited); // 這里遞歸時 node 還沒被標(biāo)記 dfsWrong(node-down, visited); dfsWrong(node-left, visited); dfsWrong(node-right, visited); add(visited, node); // 標(biāo)記太晚了 } // 正確寫法進(jìn)入節(jié)點時立即標(biāo)記 void dfsCorrect(QuadNode* node, HashSet* visited) { if (node NULL) return; if (contains(visited, node)) return; add(visited, node); // 立即標(biāo)記 dfsCorrect(node-up, visited); dfsCorrect(node-down, visited); dfsCorrect(node-left, visited); dfsCorrect(node-right, visited); }這個細(xì)節(jié)看起來微不足道但實際調(diào)試時能讓你抓狂很久。我的建議是把標(biāo)記作為訪問節(jié)點的第一個動作養(yǎng)成肌肉記憶。6.3 刪除節(jié)點時的斷鏈順序刪除四向鏈表中的節(jié)點比插入更復(fù)雜。你需要處理四個方向的鄰居而且斷鏈的順序很重要。如果順序不對可能會丟失對其他節(jié)點的引用。假設(shè)要刪除節(jié)點 BB 的四個鄰居分別是 U上、D下、L左、R右。正確的斷鏈順序是先讓 U 的 down 指向 D跳過 B再讓 D 的 up 指向 U讓 L 的 right 指向 R讓 R 的 left 指向 L最后釋放 B 的內(nèi)存void removeNode(QuadNode* node) { if (node NULL) return; // 處理上下方向 if (node-up ! NULL) node-up-down node-down; if (node-down ! NULL) node-down-up node-up; // 處理左右方向 if (node-left ! NULL) node-left-right node-right; if (node-right ! NULL) node-right-left node-left; // 最后釋放自己 free(node); }注意這里假設(shè)刪除節(jié)點后上下鄰居直接相連左右鄰居也直接相連。如果你的業(yè)務(wù)邏輯不是這樣比如刪除后需要保持某種特殊結(jié)構(gòu)那斷鏈邏輯需要相應(yīng)調(diào)整。注意刪除節(jié)點后原來指向該節(jié)點的所有外部引用都會變成懸空指針。如果你的代碼里還有其他地方持有這個節(jié)點的指針必須同步清理否則后續(xù)訪問會出問題。6.4 打印預(yù)覽時的對齊問題打印四向鏈表時如果節(jié)點數(shù)據(jù)的寬度不一致比如有的是 1 位數(shù)有的是 3 位數(shù)輸出會參差不齊。解決辦法是用固定寬度格式化輸出printf(%4d, node-data); // 每個數(shù)字占 4 個字符寬度右對齊如果數(shù)據(jù)是字符串可以用%-10s左對齊或者%10s右對齊。關(guān)鍵是統(tǒng)一寬度讓輸出看起來整齊。另外如果鏈表很大比如 100x100直接打印會刷屏。這時候可以加一個范圍限制只打印指定區(qū)域void printRegion(QuadNode* topLeft, int startRow, int endRow, int startCol, int endCol) { // 先移動到起始行 QuadNode* rowNode topLeft; for (int i 0; i startRow rowNode ! NULL; i) { rowNode rowNode-down; } for (int i startRow; i endRow rowNode ! NULL; i) { QuadNode* colNode rowNode; for (int j 0; j startCol colNode ! NULL; j) { colNode colNode-right; } for (int j startCol; j endCol colNode ! NULL; j) { printf(%4d, colNode-data); colNode colNode-right; } printf(\n); rowNode rowNode-down; } }這個函數(shù)只打印指定矩形區(qū)域內(nèi)的節(jié)點對于大鏈表調(diào)試非常實用。6.5 泛型實現(xiàn)中的類型擦除問題如果你用 Java 泛型來實現(xiàn)四向鏈表需要注意類型擦除帶來的限制。Java 的泛型在運行時會被擦除你不能用new T[]來創(chuàng)建泛型數(shù)組也不能用instanceof T來判斷類型。public class QuadNodeT { T data; QuadNodeT up, down, left, right; // 錯誤不能直接創(chuàng)建泛型數(shù)組 // QuadNodeT[] neighbors new QuadNodeT[4]; // 正確用通配符或者強制轉(zhuǎn)換 SuppressWarnings(unchecked) QuadNodeT[] neighbors (QuadNodeT[]) new QuadNode[4]; }在 C 里用模板就沒這個問題因為 C 的模板是編譯期展開的每個類型都會生成獨立的代碼。但代價是編譯后的二進(jìn)制體積會變大。選擇哪種泛型方案取決于你的項目需求。如果追求運行效率C 模板更好如果追求開發(fā)效率和跨平臺Java 泛型更方便。7. 四向鏈表與其他數(shù)據(jù)結(jié)構(gòu)的對比選型7.1 四向鏈表 vs 雙向鏈表 vs 十字鏈表特性雙向鏈表四向鏈表十字鏈表指針數(shù)量244維度一維二維二維適用場景線性序列網(wǎng)格、鄰接關(guān)系稀疏矩陣插入復(fù)雜度O(1)O(1)O(1)遍歷復(fù)雜度O(n)O(V)O(V)內(nèi)存開銷低中中高十字鏈表是四向鏈表的一個變種專門用于稀疏矩陣存儲。它的每個節(jié)點有 right 和 down 兩個指針分別指向同行和同列的下一個非零元素。和四向鏈表相比十字鏈表不存儲 up 和 left 指針因為稀疏矩陣的遍歷通常只需要向右和向下。如果你需要雙向遍歷既能向右也能向左既能向上也能向下四向鏈表更合適。如果只需要單向遍歷十字鏈表更省內(nèi)存。7.2 什么時候該用四向鏈表四向鏈表不是萬能藥它有明確的適用場景二維鄰接關(guān)系節(jié)點之間的連接是上下左右四個方向且關(guān)系是雙向的。動態(tài)增刪節(jié)點數(shù)量會動態(tài)變化不適合用固定大小的二維數(shù)組。稀疏結(jié)構(gòu)大部分位置沒有節(jié)點用二維數(shù)組會浪費大量空間。需要雙向遍歷既需要從 A 走到 B也需要從 B 走回 A。如果你的場景不滿足這些條件可能有更合適的數(shù)據(jù)結(jié)構(gòu)。比如規(guī)則網(wǎng)格用二維數(shù)組就夠了不需要四向鏈表。又比如只需要單向遍歷用十字鏈表或者鄰接表更省事。7.3 實際項目中的選型經(jīng)驗我在一個圖像處理項目里用過四向鏈表來表示像素鄰域關(guān)系。當(dāng)時的場景是需要從某個種子像素出發(fā)找到所有顏色相近的連通區(qū)域。用四向鏈表的好處是每個像素節(jié)點只需要存儲四個鄰居指針不需要存儲坐標(biāo)信息內(nèi)存占用比二維數(shù)組小很多尤其是圖像大部分區(qū)域是背景的情況下。但后來發(fā)現(xiàn)四向鏈表的維護成本太高了。每次圖像變化比如用戶涂抹都需要更新大量節(jié)點的指針。最終我們改用了并查集加二維數(shù)組的方案雖然內(nèi)存占用大一些但維護簡單得多性能也更好。這個經(jīng)驗告訴我四向鏈表適合結(jié)構(gòu)相對穩(wěn)定、增刪不頻繁的場景。如果增刪非常頻繁維護指針的成本可能會超過它帶來的好處。選型時一定要結(jié)合具體的操作頻率來評估。8. 完整可運行的代碼框架把前面所有的片段整合起來給出一個完整的、可直接編譯運行的 C 語言實現(xiàn)框架#include stdio.h #include stdlib.h #include string.h // 節(jié)點定義 typedef struct QuadNode { int data; struct QuadNode* up; struct QuadNode* down; struct QuadNode* left; struct QuadNode* right; } QuadNode; // 創(chuàng)建節(jié)點 QuadNode* createNode(int data) { QuadNode* node (QuadNode*)calloc(1, sizeof(QuadNode)); node-data data; return node; } // 創(chuàng)建網(wǎng)格 QuadNode* createGrid(int rows, int cols) { QuadNode** grid (QuadNode**)malloc(rows * sizeof(QuadNode*)); for (int i 0; i rows; i) { grid[i] (QuadNode*)calloc(cols, sizeof(QuadNode)); for (int j 0; j cols; j) { grid[i][j].data i * cols j; } } for (int i 0; i rows; i) { for (int j 0; j cols; j) { if (i 0) grid[i][j].up grid[i-1][j]; if (i rows - 1) grid[i][j].down grid[i1][j]; if (j 0) grid[i][j].left grid[i][j-1]; if (j cols - 1) grid[i][j].right grid[i][j1]; } } return grid[0][0]; } // 訪問標(biāo)記簡化版用節(jié)點內(nèi)置標(biāo)記 // 實際項目中建議用哈希表這里為了代碼簡潔用內(nèi)置標(biāo)記 void resetVisited(QuadNode* topLeft, int rows, int cols) { QuadNode* rowNode topLeft; for (int i 0; i rows rowNode ! NULL; i) { QuadNode* colNode rowNode; for (int j 0; j cols colNode ! NULL; j) { colNode-data colNode-data; // 占位實際需要單獨的 visited 字段 colNode colNode-right; } rowNode rowNode-down; } } // 打印網(wǎng)格 void printGrid(QuadNode* topLeft) { if (topLeft NULL) return; QuadNode* rowStart topLeft; while (rowStart-up ! NULL) rowStart rowStart-up; while (rowStart-left ! NULL) rowStart rowStart-left; QuadNode* rowNode rowStart; while (rowNode ! NULL) { QuadNode* colNode rowNode; while (colNode ! NULL) { printf(%4d, colNode-data); colNode colNode-right; } printf(\n); rowNode rowNode-down; } } // DFS 遍歷用外部數(shù)組標(biāo)記 void dfsTraverse(QuadNode* node, int* visited, int totalNodes, QuadNode* base, void (*visit)(QuadNode*)) { if (node NULL) return; int idx (int)(node - base); if (idx 0 || idx totalNodes) return; if (visited[idx]) return; visited[idx] 1; visit(node); dfsTraverse(node-up, visited, totalNodes, base, visit); dfsTraverse(node-down, visited, totalNodes, base, visit); dfsTraverse(node-left, visited, totalNodes, base, visit); dfsTraverse(node-right, visited, totalNodes, base, visit); } // BFS 遍歷 void bfsTraverse(QuadNode* start, int* visited, int totalNodes, QuadNode* base, void (*visit)(QuadNode*)) { if (start NULL) return; QuadNode** queue (QuadNode**)malloc(totalNodes * sizeof(QuadNode*)); int front 0, rear 0; queue[rear] start; visited[(int)(start - base)] 1; while (front rear) { QuadNode* node queue[front]; visit(node); QuadNode* neighbors[4] {node-up, node-down, node-left, node-right}; for (int i 0; i 4; i) { if (neighbors[i] ! NULL) { int idx (int)(neighbors[i] - base); if (idx 0 idx totalNodes !visited[idx]) { visited[idx] 1; queue[rear] neighbors[i]; } } } } free(queue); } // 訪問函數(shù) void printNode(QuadNode* node) { printf(%d , node-data); } // 主函數(shù) int main() { int rows 3, cols 4; int totalNodes rows * cols; QuadNode* topLeft createGrid(rows, cols); QuadNode* base topLeft; printf( Grid Preview \n); printGrid(topLeft); // 找到中間節(jié)點 (1,1) QuadNode* start topLeft; for (int i 0; i 1; i) start start-down; for (int j 0; j 1; j) start start-right; printf(\nStart node: %d\n, start-data); // DFS 遍歷 int* visited (int*)calloc(totalNodes, sizeof(int)); printf(\nDFS: ); dfsTraverse(start, visited, totalNodes, base, printNode); printf(\n); // BFS 遍歷 memset(visited, 0, totalNodes * sizeof(int)); printf(BFS: ); bfsTraverse(start, visited, totalNodes, base, printNode); printf(\n); free(visited); return 0; }這個框架可以直接編譯運行輸出會顯示網(wǎng)格預(yù)覽、DFS 遍歷結(jié)果和 BFS 遍歷結(jié)果。你可以基于這個框架擴展自己的業(yè)務(wù)邏輯。我在實際使用中發(fā)現(xiàn)把訪問標(biāo)記從節(jié)點內(nèi)置字段改成外部數(shù)組雖然代碼稍微復(fù)雜一點但好處是遍歷完后不需要重置節(jié)點狀態(tài)而且同一個鏈表可以同時進(jìn)行多次不同目的的遍歷互不干擾。這個設(shè)計決策在需要頻繁遍歷的場景下特別有價值。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
可以免费观看的AV| 网站A V在线| 看黄片视频免费| 欧美综合狠| 又摸又舔在线观看网站| 97国产成人精品免费视频| 青草精品视频一日本久久久久网站| 亚洲五月婷| 国产一级高清免费观看| 亚洲成人妻日韩在线| 精品无码一区二区三区色欲| 色综合1991| 九九无码久久精品视频| 一级黄色性爱A级片| 国产日韩人人| 欧美A√综合网| 免费看久久久性性| 日本一区视频在线观看| 免费看污网址| 中文久久爆乳| 91欧洲国产成人久久精品网站| 91欧美偷拍| 91精品国产高清久久久久久,亚洲成人| 国产热av| 欧美 亚洲 综合 制服 另类| 欧美午夜色妇色鬼| 亚洲AV高潮| 强奸乱伦av电影| 欧美色狠| 综合少妇网| 国产精品3| 日韩AV中文字幕电影| 99自拍视频在线观看| JIZZJIZZ亚洲女人被躁| 蜜桃久久一区二区| 大香蕉日韩欧美| 精品一二三区女同| 97日视频| 亚洲情色在线| 屌妞视频久久久久久久久久久久| 国产精品久久久久久 百度| 久久久久久九九九九| 日日日大屁股骚女人精品| 中文无码一二三区| 99国产人成精品| 99国产精品视频尤物| 午夜性生活av免费在线看| 色偷偷综合91久久噜噜| 精品国产综合久久福利,热99这里有精品综合久久,99热这里只有免费国产精品,精 | 精品人妻一区二区三区视频在线| 综合97久久| 亚洲天堂第一页| 后入内射蜜桃臀| 国产农村妇女一区二区| 狠狠操综合| 另类专区在线观看| 色综合久| 婷婷五月天伊人| 中文字幕一区日韩精| 一区 欧美 日韩 麻豆| 大香蕉操久久| 亚洲日产专区| 麻豆九九九| 男人亚洲91首页在线| 精品成人av一区二区三区在线| 成年人一级黄色毛片大全在线观看| 成人精品在线免费视频| 久久精品国产亚洲妲己影视| 樱花蜜乳av| 国产强奸乱伦xd| 无码外流操逼视频| 国产啊v在线免费播放| 97精品在线视频| 另类图片天天影视| 秋霞免费无码视频日韩A片| 丁香婷婷五月| 黑人美精品 A片| 图片区小说区| 青青爽| 婷婷三区| 成人精品一区二区三区| 欧美情色亚洲| 久久久999| 精品一区二区在线针对华人免费观看这里只有精品免费观看 | 亚洲最大的黄色电影网站。| 国产丝袜美女诱惑| 丝袜色综合| 爱丝福利| 精品久久久av无码免费| 福利操逼| 小草精彩毛片| 久久精品99| 日本高清一本二本免费不卡| 熟妇人妻丰满久久久久久久无码| 91午夜无码| 红杏大香蕉| 大香蕉色欲AV| 三级日韩一区二区三区| 久久人人看| 亚码人妻| 熟妇的味道HD中文字幕| 中文字幕av色| 久久久一区二区三区麻豆| 国产三级资源在线观看| 五月天久久婷婷亚洲| 欧美一级二级三级| 国产日本久久免费精品| 国产视频小说| 三级精品三级在线观看| 色色色色色色色色色色色色色色综合| 四季av一区二区凹凸精品小说| 国产乱伦亚洲色图高清无码| 久久国色天香香蕉| 99中文字幕| ?亚洲伊人伊成久久人综合网| 曰本精品久久久| 欧美综合另类| 96精品在线| JIZZJIZZ国产精品喷水| 91精品国久久久久久无码| 蜜臀久久99精品久久久电影| 日韩欧美偷拍美女视频| 极品尤物女神在线观看| 夜夜爽爽夜夜精品视频| 手机在线看片免费人成视频| 人妻蜜桃臀| 日本性爱不卡视频| 97爱碰| 国产丝袜美女在线一区| 亚洲一区制服诱惑| 天天色怡春院| 中文字幕在在线观看网站| 精品视频一二三中文| 操碰97| 久久天堂| 99xav| 人人操人人插 - 百度 - 百度| JULIA人妻风俗店中出电影| 色逼综合| 欧美日韩一干二干| 亚洲美女自拍偷拍视频| 伊色久人大在线| 先锋精品av色鲁| 欧亚日韩中文在线| 超碰97网址| 国产精品久久久久久无码红治院| 熟女露脸激情自拍视频| 色综合一区二区三巨| 国产性爱强奸乱伦大全| 亚洲av总站| 免费观看性欧美一级| 久久日本熟妇熟色高清| 国产女生在线| 夜色91| 少妇同性| 黄网色一区二区三区四区精品| 日本幼女18+| 久久久亚洲精品电影免费看| 日本欧美亚洲高清在线看| 美女让帅哥通她小鸡鸡| 亚洲男人天堂Av| 伊人一区二区在线播放| 国产又长又大又粗的视频| 婷婷色婷婷| 日B操| 97国产|免费| 德国一二三不卡| 成人乱码一区二区三少妇| 密臀在线视频| 国产精品亚洲日韩骚欢乐谷最新地址发布页huanieguty性屋娱乐妖精视频 | 狠狠久久手机视频精品| 另类老少妇| 大鸡吧尹人在线| 欧美成人黄网色网站| 91国模| 欧美熟女妇同| 精彩国产视频播放1区2区| 国产综合网站在线播放 | 99丝袜福利在线播放| 成人a大片在线观看| 一本久久久精品| 亚洲AV高潮| 五月婷婷色| 欧美性爱视频免费一区一A| 亚洲欧美人妻| 久久东京热成人| 久久久专区| 亚洲 图片 综合91| 97综合在线| 99精品欧美一区二区三区桃色| 国产路线专区| 精品久久久久综合无码| 国产日本顶级一区二区三区| 国产又长又大又粗的视频| 欧美97视频| 久久久久骚| 国产无码一二三区| h无码动漫在线观看| 日本一区二区中文字幕久久| 天堂性色| 国产精品一区二区三区在线| 久久久久久久久国产| 啊灬快c我灬啊灬用力灬啊灬-国产精品性做久久久久久-成人AV | 精品人妻一区二区三区四区| 色777999综合| 天综合网欧美| 精品人妻一区二区三区免费视频| 俞拍久久国应视频| 成人小电影网站tex| 中文字幕第95页| 亚洲日韩少妇一道本视频| 蜜桃视频一区二区三区在线观看| 国产美脚女优尤物在线观看| 亚洲、日韩、综合、另类| 看日韩美女二区三区免费操逼视频 | 在线亚洲欧美| 最好看的中文字幕在线2018| 草草网站影院白丝内射| 亚乱色| 久久久久国产精品喷潮免费观看臀| 久久久久免费看少妇A片特黄| 中国操逼无码| 亚洲日韩美国人妻| 亚洲综合中文字幕有码| 精品久热| 日韩一级二级在线| 91AV天美在线视频| 色九九久九九| 中文AV制服乱伦| 黄色片一区二区三区四区五区| 女人与公拘交酡2020视频| 国产无码精品成人| 亚洲第一无码播放立川理惠| 99在线精品观看99| 中文字幕一区二区三区蜜臀| 人妻少妇精品久久久| 超碰97亚洲区| 久久岛国| 国产欧美成人第一页在线观看 | 亚洲极品| 国产精品人妻无码久久久互動交流| 边做饭边操逼逼| 久久黄色视频一区二区三区| 五月丁香六月婷| 综合天天网| 天天综合站| 亚州综合网| 99久国产精品午夜性色福利| 国产无码一二三区| 这里是精品| 亚洲情色综合网| 色噜噜国产精品视频一区二区| 国产精品片| 亚洲精品国产熟女| 亚洲 综合 欧美| 欧亚揄拍偷拍精品视频| 久久久96| 91精品久久综合熟女| 五月黑AⅤ| 亚洲 另类 丝袜 自拍 动漫| 91熟女丨91老女人| av无码精品久久久久| 六六久久日韩不卡| 欧美丝袜美女电影一二三四区| 无码人妻一区二区三区免费九色| 国产 日韩 欧美 中文 另类,国产 欧美 另类 制服 变态,高清 日韩 欧美 中文,高 | 欧美日韩香蕉| 黑人精品久久97| 狠狠爱大香蕉| 性爱1区| 国产亚洲色婷婷99精品91| av影院十区| 搡老女人老妇女AAA一VU麻豆| 亚洲欧美精品一区天堂久久| 午夜精品久久久久久久第一页按摩| 无码外流操逼视频| 色盈盈影院| 97天天| 午夜理论片在线观看免费| 伊人97色天使| 性综合网| 综合国产97| 国产精品第一页国产大屁股视频免费区| 久久综合亚洲色1080p| 啊啊啊啊啊啊啊国| 熟妇乱伦一区二区| 婷婷香蕉欧美在线一区二区三区| 青青草在线视频播放器| 婷婷五月天av| 少妇久久久久久久久| 日本在线视频导航| 国产精品高朝久久久久久久| 亚洲成人福利电影免费| 精品美女久久一二三| 干我久操| 骚逼一区二区| 久久综合亚洲色1080p| 麻豆性爱视频在线播放| 啪啪啪东京| 久久免费看高潮毛片韩国| 四虎免费在线播放| 精品人妻一区二区乱码一区二区| 好属操| 五月丁香婷婷色| 性高潮久久久| 五月香婷婷| 欧美另类天堂| 开心五月深爱五月| 亚洲在线欧美| 亚洲精品一二三四区| 1769成人国产精品视频| 国产超碰在线一区| 午夜无遮挡男女啪啪视频| 超碰久久草| 不卡av在线中文字幕| 玖玖爱一区在线| 色就色综合| 动漫av中文| www…国产操逼| 久久久一二三四区| 暖暖精品二区三区观看| 人妻一二三区| 久热精品在线| 天堂日本亚洲欧美| 国产在线精品偷| 美女诱惑久久| 亚洲有码第一页| 丁香五月天激情网站| 亚洲色宗合| 国产精品视频播放| 99色热| 九九视频黄色片| 蜜臀99久久精品| 青青青国产| 午夜120视频在线观看| 国产美女高潮视频| 一区二区三区四区姦女| 熟女人妻一区二区三区| 国产精品久久久啊| 久久激情视频| 内射黑人| 99热这里只有精| 熟女五十路一区二区三| 欧亚日韩中文在线| 玖玖草久草99蜜月一区二区三区| 啊啊啊用力在线观看| 免费看黄视频亚洲网站| 五十路熟女人妻一区二区在线观看 | 青青草日韩无码| 国产精品无码成人精品| 天美传媒精品一区二区| 997色在线| 久久不卡一区二区| 亚欧美天堂在线| 国产精品视频白浆免费| 午夜视频久久久久一区| 日本不卡在线二区三区| 亚洲男人天堂2013| 97这里都是精品| 337p大胆噜噜噜噜噜91Av| 中文字幕日韩电影人妻| 国产熟女精品一区二区| 91天堂丝袜美腿| 啊啊啊不要好爽日韩无码一区| 俺去也婷婷| 色婷婷激一区二区三区 | 97AV爱| 亚洲四虎熟女精品| 色嗨嗨在线| 国产精品一区二区a| 东京热毛片调教| 色娱乐色呦呦夜夜夜夜av| 2020视频1区2区3区| 亚洲精品aa久久伊人| 国产中文大片资源中文字幕 | 女人爽到高潮潮喷18禁网站| 欧美不卡二区| 久久91视频| 亚洲色图尤物视频 | 亚洲免费精品一区| 日本一区二区电影网站| 久久啊哟| 1区2区3区在线视频| 丁香六月啪| 一区二区三区精品视频| 日韩少妇一区二区三区| 国产精品欧美日韩久久| 欧美日韩操逼动图| 温婉少妇玩3p| www.99视频| 五月综合激情| 久热伊人99re| www.操| 黑人天8A∨高清网站| 人人污日韩一区二区| 九九热超碰97亚洲最新香蕉| 97视频在线观看高清资源| 91亚洲影院综合| 女人的天堂大香蕉网| 天操老女人| 日韩精品电影| 揉揉揉夜夜| 九九热九九| 免费观看网黄| av资源在线观看少妇| 色婷婷六月| 美女人妻色网站| 9精品在线| 自拍第一页| 97超碰香蕉| 韩三级a视频在线观看| 国产AV激情无码久久无码 | 久操九九九九| 精品96久久| 青青青草原| 亚洲精品九九九| 激情抓乳插进去啪啪啪日韩 | 国产精品免费1区2区视频| 亚洲欧美日韩免费电影| 男人天堂一区二区| 91久久国外网| 日韩无限资源| 午夜福利视频在线一区| 偷窥自拍亚洲色图| 91欧美丝袜| 好爽视频在线观看视频| 日韩国产成人自拍视频| 99久久这里只有精品| 国产小炒后入式| 色路综合| 女人被男人桶爽视频网站| 九九激情网| 丝袜av一区二区三区| 九九热三级片| 男女真人网18| 国产日韩人人| 成人av毛片在线观看| 国产一区二区视频在线播放| 91挑色欧美| 欧美96精品在线| 99精品久久久久久久婷婷| 97天天搞在线| 九九九九精品在线| 日韩AV无码中文一区二区| 97视频观看| 99re这里只有| 秋霞曰韩R级| 欧美色图成人网一区二区 | 五月婷婷激情综合| 伊人久久亚洲色欲综合网站 | 天操天操夜操夜月月年年操操| 超碰久久中文| 一区二区视频你懂的| 偷拍视频青青草在线视频| 亚洲一区二区三区中文字幕| 在线只有精品| 精品人妻一二三四区视频| 青青草公开在线免费不卡视频| 俺去啦俺来也久久综合| 91麻豆天美国产欧美| 啊啊啊啊啊啊啊在线| 国产精品美女视频诱惑| 久久婷五月| 久久久免费懂色| 做爱A级亚欧| 香蕉一区二区三区在线视频| 夜夜欧美| 天天爽爽爽爽| 欧美日韩精品久久久久久久久东北老熟妇| 亚洲最新中文字幕免费| 久色99999| 黄色免费一级在线毛片| 后入 亚洲 美女 射| 欧美熟妇精品黑人巨大91| 无码逼| 猛交交| 国产精品3| 91制服丝袜中文字幕| 久久精品美女一区| 久久精品无码熟妇一区二区三区视频导航 | 99热99re超碰精品| 78操B| 99综合视频一体| 五月天亚洲色图| 91oumei| 欧美宗合网| 天天肏美女| 亚洲爽图| 欧洲亚洲人妻无码中字久久三区四区| 天堂无码精品国产久| 99热在线不卡| 四虎国产精品永久地址入口| 亚洲影视高清第一页| 日韩人妻中文视频| 97国产精品久久久久| 人妻av在线| 偷偷人人精品女女久久| 99啪啪| 一区AV| 少妇人妻精品| 亚洲 欧美 手机在线观看| 亚洲男人天堂网站| 美女黄色一级A视频| 久久精品久| 欧美天堂超碰97| 日韩av一级黄片| 亚洲精品97p| 日本天天人人狠狠在线日美女 | 蜜臀无码视频在线观看| 试看福利| 亚洲欧美日韩精品久| 啊啊啊爽爽| 国产白领连续中出在线观看| 天天射天天操天天干天天吃2018| 97综合在线观看| 高潮的A片激情扒开一区| av草草在线电影| 五月综合久久| 人妻一二三区| 欧美偷拍| 小骚逼被操的爽不爽| 丝袜美腿诱惑亚洲欧美视频在线观看| 欧美大波激情xxxx| 91热热色| 欧美综合 站| 91一区二区| 欧美大香蕉同搞| aa片毛片| 日韩欧美三级| 91最新综合| 黄片不用下载在线观看| 日韩熟女三十乱伦| 大香蕉日韩| 国产AV人人 夜夜人人澡| 久精品无码av一区二免费国产在线观看 | 中国熟妇| 国产精品久久久777| 欧美熟女丝袜| 久久精品亚洲东京热色播| 黄片免费久久久久久久| 97色在线视频| 日韩大香蕉AV影片| 欧美 亚洲 91| 中文字幕天天天天天| 天天干天天爽| 久久久成人国产精品无码| 丁香九月婷婷| 久久系列| 国语精品av| Aa东京男人的天堂| 日韩淫色网| 9超碰免费| 夜夜肏2021| 亚洲一区二区麻豆影院| 国产福利av精彩对白| 久操操AV电影| 久久久久亚洲AV无码专区少妇| 999综合网| 久久久久久综合久久伊人蜜月| 亚洲天堂电影网| 久久一二三四不卡 | 中文字幕一区二区三四五区日日骚| 婷婷午夜| 制服乱伦| 午夜精品一区二区三区三上悠亚| 免费观看啪视频| 久久精品中文字幕无码l| 久草国产在线视频| 国产熟女完整版中字| a片久久久久久久久久久久 | 秋霞视频一区二区 | 97香蕉碰碰人妻国产欧美| 综合影视国产无码| 一个色导综合| 粉嫩av在线| 亚洲av青草久久一区二区| 午夜毛片亚洲精品片国产久久久| 少妇久久久久久| 97亚洲综合影院| 97在线免费观看视频| 人人性爱视频免费| 亚瑟国产精品久久无码| 青草精品视频日本久久久久网站在线| 97精品视频| 国产精品999aaa| 福利社区午夜一区二区| 色哟哟511老熟女| 97精品熟女少妇一区| 亚洲AV噜噜狠狠网址蜜桃动漫| 在线可观看的黄色网址| 91人妻Pr| 日本 欧美 亚中文字幕| 乱码熟妇人妻久久久| 精品国产72| 久久r精品| 青青青在线高清视频在线一二三四区| 91亚洲人| 久久综合亚洲色1080p| 91操人| 超碰人妻在线| 久久神马影院| 97在线亚洲| AVE乱伦| 国产理论视频在线播放| 婷婷久久综合久| 国产25页| 天躁夜夜躁2021| 极品国产内射| 欧美精品自慰系列寂寞少妇| 超碰亚洲欧美日韩无| 欧美在线 亚洲| 好涩综合| 性暴力欧美猛交在线直播| 九九久久精品| 蜜臀99999| 久久蜜桃一区二区| www.av在线视频| 色久综合| 99这里都是精品| 一区二区三区国产在线播放| 黄片无码在线制服| 九九热超碰97亚洲最新香蕉| 白嫩91在线亚洲| 操逼免费视频无码国产| 伊人亚洲国产一成人久久精品,久久| 日本裸体久久色噜噜| 一级AAA片一区二区三区| 日韩操啪| 亚洲欧美日韩夜夜| 天天躁狠狠躁av| 少妇综合| 99丝袜福利在线播放| 蜜臀在线看片| 强奸乱伦免费网站| 亚洲AV免费在线观看| chaopen97久久| 国产av又色又爽又黄| 久草精品热视| 欧美色图20P| 综合自拍| 欧洲精品一二三在线| 中文字幕一区二区三区四区在线视频| 天天弄天天操| 一二区在线观看视频| 亚洲精品xxx| 国产精品久久久蜜臀| 欧美色狠| 亚州伊人色综台| 96一区二区三区| 成人国产精品三级A片| 九九九九免费高| 日夜精品| 欧美v日韩欧亚洲电影天堂色诱,国产传媒| 青青草中出视频| 久久亚洲色图中文字幕| 人人操人人色网| 久久欧美按摩999| 久久久999| 日韩97超碰中文字幕| 午夜毛片亚洲精品片国产久久久| 婷婷色婷婷| 中国和日本人色哪个不下载能放| 亚洲综合在线视频| 日本韩国五十路六十路七十路老熟女作爱视频网站| 大香蕉五月天| 日韩欧美女求操每天更新| 日韩激情啪啪啪| 欧美成人色| 一区二区三区视频国产免费| 校园春色中文字幕AV| 久久精品国产96精品亚洲拳交| 国外91| 婷婷综合在线| 日韩大香蕉| 亚洲国产一区二区三区在线| 91精品无码久久久久久久| 国产欧美一区二区| 人人操人人操人人人操| 91AV天美在线视频| 成人无码影片视频在线| 久久久熟女一区| 9999免费精彩视频| 放黄片放3级黄片没穿衣服| 欧美18禁91| 操逼操逼视频操逼| 亚春色色| 综合色图亚洲欧美| 深夜国产一区二区三区在线看| 亚洲日韩东京热一区| 国产日韩欧美三级片| 东京热毛片177b2viP| 91在线欧色| 日本操逼二区| 超碰诱惑| 人妻少妇精品久久久| 久久久久久久久成人av解说| AV女资源| 丝袜喷水在线| 盗摄女人妻在线| 亚洲在线91| 操死我了嗯嗯嗯| 另类小说五月天| 中文字幕av亚洲精品| 九九热免费国产视频婷婷伊人| 高清国产成人无码| 大粗鳼巴久久久久| 色色色色色色色色综合| 久久色情| 八人操人人摸人人看| 国产精品97视频| 磁力99AV| 人人天天欧洲| 免费在线黄片视频| 欧美一级黄色免费专区| 婷婷五月天色网| 国产精品网站免费| 无码又爽又硬又激情免费视频| TS人妖另类精品视频系列| 亚洲做性| 久久久久网站-538在线视频-欧美永久乱码 | 绯色一区二区三区不卡少妇| 久久一二三四五六七八九区| 97久久精品亚洲中六字幕| 亚洲欧美国产成人综合不卡| 精品国产91内射久久| 久久久亚洲精品中文字幕人妻| 99re在线精品78| 天天干2区3区| 久久东京国产精品视频| 秋霞免费AV| 免费福利视频中文字幕| 亚洲麻豆av一区二区| 亚洲欧洲综合| 欧美在线亚洲| 国产精品97超碰| 欧美日韩亚洲国产中文永久天天看| 亚洲限制级在线| 92福利社视频| 人妻少妇av在线观看| 中文字幕奈奈美被公侵犯| 一个色导综合| 欧美性爽xyxOOOO| 日语五十路和六十路亚洲国产精品| 素人伊尹大香蕉免费下载视频| 精品国产综合久久福利,热99这里有精品综合久久,99热这里只有免费国产精品,精 | 欧美色日本| 私色综合网| 日本一本一区二区三区四区五区欧美日韩中文字幕 | 超碰人妻久久| 男人的天堂va| 亚洲中文丝袜美腿诱惑字幕| 欧美激情在线观看视频| 九九九偷拍| 四虎884| 国产极品美女高潮无套在线观看| 国产欧美在线观看免费观看| 婷婷在线视频在线观看| 大屁股人妻女教师撅着屁股| 欧美区亚洲区偷拍区| 伊人网免费视频| 久久首页| 九九综合久久中文字幕| 国产精品一区二区三区,亚洲综合| 一级片在线观看高清无码| 中文字幕一区二区三区四区在线视频| 一区操逼| 激情小说成人日本无码一| 簧片免费看视频| 综合色图区| 青青青国产| 有码人妻系列| 99操| 亚洲人久久久网| 亚洲欧美91√| 亚洲欧美首页| 日韩欧美大片免费高清啪啪| 在线观看高清AV| 日韩人成网站在线播放| 亚洲丝袜二区| 欧美色图偷拍另类| 偷拍99| 亚洲人天堂| 国产欧美精选激情视频| 中国亚洲呦女专区| 一级@啪啪视频| 精品高清牛人盗摄一区二区三区中文字幕A片免费在线观看 | 综合久久97| CCYY草草影院地址入口| 亚洲美女自拍偷拍视频| 91在线页| 精品美女少妇一区二区三区| 精品夜夜澡人妻无码AV| 岛国1区2区3区在线观看| 国产视频人人网| 亚洲中文国际强奸字幕| 亚码激情| 超碰偷拍| 欧美成人性爱视频在线播放| 性爱av在线免费观看| 无码一区二区三区四区五区六区七区八区九区十区视频 | 欧亚久久偷拍视频| 蜜桃午夜视频一区二区| 亚洲麻豆av一区二区| 精品成人av一区二区三区在线| 91 丝袜在线| 久久成人网站| 国产一区二区三区免费视频在性观看| AV九九| 亚欧中文字幕在线视频| 天天拍夜夜| 黄aaaaaaaaaaaaaaaaaa色网站| 射 色综合| 欧美后入式| 国产精品96久久久久久| 手机在线中文字幕国产 | 蜜臀久久久国产| 好色综合| 爽爽淫人网| 国产人人干| 日韩免费在线视频观看| 爱av免费| 中文字幕一区二区三四五区日日骚| 国产高清午夜成人在线观看| 亚洲精品久久久久久久蜜桃臀| 精品无码人妻一区二区免费蜜桃| 台湾一区国产高清在线| 99这里有精品视频| 久久日韩肥臀| 亚洲AV无码AV吞精久久久久 | 黄色视频特级毛片| 宗合情欲网| 国产女大学生AV| 色久桃花影院在线观看| 精品国产国产AV| 97香蕉网| 蜜桃中文字日产乱幕4区| 色约约一区=区三区| 婷婷久久网| 吊色| 婷婷精品视频| 人澡逼| 成人综合久久精品色婷婷| 校园春色中文字幕AV| 淫荡熟女乱伦网| 熟女自慰久久久| 51久久夜色精品国产麻豆| 色一射色一射| 98人妻精品一区二区色欲| 久久天天摸| 国产色图乱伦| 九九久久九九久久| 欧美精品三级黄片| 精品久久青青草| AVE乱伦| 日韩av熟女一区二区三区成人| 亚洲欧美成人网站AAA| 欧美黑人性猛交91| 日产欧美电影一区二区三区| 丁香九月婷婷| 婷婷五月av| 精品人妻av区天天看片| 992这里有精品| 亚洲国产丝袜熟女av| 99爱久久视频频| 婷婷丁香九月| 亚洲精品蜜桃久久久久久久| 操逼网站视频漫画国产| 欧美色图小说综合| 七久久久| 性夜影院爽黄A爽免费动漫| 日韩午夜国产| 黄色av一区二区在线| 97少妇人妻中文字幕久久| 亚洲中文字幕精品久久久久久直播| 91丰满| 啊a一区在线| 亚洲欧洲精品视频发布| 97超色| 天无日色综合| 性爱乱伦视频免费| 青青草综合在线| 小草精彩毛片| japan日本高清乱xxxx| 中文字幕精品亚洲熟女| 97天天搞在线| 日韩一区二区精彩视频| 干妹子| 综合网欧美在线| 无码高清国产AV| 熟妇无码视频三区| 欧美se亚洲| 久久久久国产精品喷潮免费观看臀| 999999精品| 福利大香蕉| 吻戏激情性巴克| 精品中文字幕一区二区l - 百度| 麻豆天天躁天天揉揉AV| 日韩国产十八禁| 黑人黄片在线免费观看| 欧美大波激情xxxx| 亚洲有薄码区久久在线一区| 少妇被玩视频二三区| 一级特级aaaa毛片免费观看| 日韩av无码网站| 啊嗯嗯啊好大好爽| 亚洲免费精品一区| 久热91| 日韩精品国产一区二区| 极品色| 91精品丝袜久久久久久无码人妻| 性爱视频无打码在线观看| 美女一区二区国产精品| 欧美色乱| 欧美亚洲特P| 亚洲欧美国产中文字幕| 四虎 精品 WWW| 伊人激情五月天一区二区| 亚洲天堂精品日韩电影| 日韩八十路老熟女| 欧美暴力猛交| 日韩乱中文| 国产无码高清操逼视频| 激情综合网激情综合| 午夜AV污污污| 久草热制服丝袜在线观看 | 超碰性爱97| 天天摸,夜夜摸| 一,爱啪啪,在线免费视频| 欧美性爱无码一区二区三区| 爱逼综合| 爱爱动态60秒| 超碰诱惑| 亚洲资源站| 国产精品电| 青青伊人久久| 日欧美色| 九九热这里只有在线精品视 伊人草 成人菠萝蜜视频在线观看 | 国产亚洲精品一区二区三区| 天天色图| 天啪| 97国产精品| dy888午夜老子影视达达兔 | 国产AV无码AV| 亚洲无码久久久久久久| 一级A片女人高潮叫床| 国产午夜精品理论片一二三区区| 91第一页| 色淫网站优优视频| 青青伊人加勒比海| 欧美78| 久噜噜| 欧美日韩青操| 裸体美女久久久| 亚州精人品大香蕉| 大香蕉操久久| 麻豆60秒| 亚洲情色五月天| 嗯嗯嗯不要不要免费视频| 国产传媒日本欧美专区| 日韩78m视频| 制服中出中文人人精品| 欧美综合传媒| 97国产精品久久久久| 欧美图片色五月天| 欧美色图99| 天天色图| 日躁天天爽爽| 日韩99精品视频综合区| 国产AV无码AV| 久久性爱大全| 97爱爱爱综合| 歐美一級亂黃99在綫精品| 久久国模av| 1.igao73.com 加入收藏 免费专区 国产精品 中文字幕 日韩精品 欧美精品 精彩 | 国产精品久久久久久照片| 日韩欧美成人性爱在线| av一区二区三区 中文| 人人色97| 黄总AV色图| 中文熟女五十乱码在线| JuliaAnn丝袜熟女系列| 91综合色噜噜| 青娱乐久久艹| 婷婷尹人大香蕉免费| 97在线欧洲| 91亚洲黄色网| 偷拍 欧美 日韩| 午夜高清成人在线视频| 女人爽到高潮久久久| 伊人伊人LD| 欧美啪啪啪91| 色综合久久av| av天天在线观看| 蜜臀亚洲中文| 999色欧美中文字幕| 黑人娇小av在线播放| 亚洲无码久久久久久久| 中文字幕一区二区在线日韩精品| 色五月激情网| 亚洲 中文字幕 精品| 一区二区三区视频国产免费| 欧美亚洲丝袜人妻制服99| 色狠人在线99| 久久 精品| 男人午夜天堂| 女人爽到高潮潮喷18禁网站| 午夜精品久久久久| 国产精品久久泡妞网站| 亚洲第2页| 夜夜操2028| 天天色综合影视网| 奇米狠999| 超碰久久性爱| 久久久555| 欧美日本中字另类在线| 日本丝袜美腿人妻九九| 国产精品久久久久久久久久久久久久| 久久国产逼| 东京热激情视频一二三区 | 黄片aaaaa一区| 91中文精品日韩欧美在线| 天天色综合影视网| 很很热性爱视频| 亚洲综合888| 17c嫩草51久久91嫩草| 十八禁av无码免费网站APP| 7月婷婷综合| 激情小说亚洲| 婷婷精品视频| 91亚洲黄色网| 伊人一级免费黄片| 亚洲不卡不卡中文字幕不卡| 夜夜性| www网站黄| 蜜桃视频啊啊啊啊| 麻豆久久一区二区三区| 吻戏激情性巴克| 欧美色九九| 精品久久人妻成人网| 五十路熟女,国产欧美精品区一区二区三区| 亚洲天天操| 在线国产探花| 欧亚三区动漫| 日韩性爱电影一区| 欧美日日人人天天| 91人妻素女| 搞中出视频在线观看| 国产精品成人久久一区二区三区| 极品丝袜无码| 精品欧美老熟女一二区| 天天欧美色| 天天插网| 97色97好| 亚洲无码超碰免费| 91网站视频在线观看| 中日亚韩免费视频| 试看福利| 99久久精品国产高潮| 九七毛片九九毛片| 双插性欧美一二三区| 亚洲偷91色| 亚洲二区精品在线观看| 亚洲女优有码无码高清| 91成人18| 一区二区三区美女超清| 免费中文在线| 俺也射| 欧美日韩性爱视屏免费看了| 花花AV导航| 91丝袜美女| 久久无码一区二区二三区性色| 久久久久网站-538在线视频-欧美永久乱码 | 国产精彩女在线观看视频| av毛片aaaaa免费看| 性爱AV天堂| 九九亚洲视频| 国产精品视频在线观看| 精品乱子一区二区三区99| 国产免费操逼| 后入式999| 97国产色综合| 国产无码三级视频在线观看| 色五月天AV| 亚洲AV无码久久久国产精品| 久操频道免费在线呗看| 91丝袜美女| 激情综合网五月婷婷五月天| 中文字幕精品三级久久久| 丰满欧美少妇| 熟女色综合久久| 欧美BT 亚洲色图| 亚州再线| 日韩黄片视频试看| 久久久555| 97色涩| 女人爽到高潮潮喷18禁网站| 欧美高清无码免费视频高清版| 97久久国产亚洲精品超碰热| 久草婷婷| 激情网色| 日韩无码人妻| 亚州男人的天堂| 97视频观看| 亚洲精品三| 五月天婷婷在线看| 日韩无码第3页| 人夜夜精品网站香蕉嫩草| 亚洲最新a在线观看| 老司机福利青青草| 亚洲自拍青操视频| 好吊色一区| 禁片 高清 在线观看视频网站| 18禁无码永久免费无限制| 精品少妇99| 亚洲区限制级 99| 情侣开房子拍 日韩无码 女的很漂亮| AV无码久久久精品| AV天堂国产| 欧美春色| 中文字幕av片| 日韩视频小说在线观看| 日日日日日| 久综合网| 丰满人妻一区二区三区大胸懂色| 91春色| 91精品老女人| 久久这里只| 欧美性五月| 91N综合网在线| 91少妇香蕉久久精品| 中文字幕一区 二区三四五 区日 日骚 | 熟妇操花| 亚欧无码在线| 国产无马视频| 天堂v无码免费视频| 久久久久久久9| 亚洲图片欧美偷拍| 亚洲精品不卡一二三区| 熟女AV一区| 久久久久亚洲精品| 狠狠躁AV| 一牛影视久久久一区二区三区| 少妇超碰在线| 日韩一级二级| 影音先锋国产精品| 欧美日韩 强奸乱伦| 操逼1区| 久久久久久精品免费看A级| 激情熟女12P| 波多野结衣AV无码一区| 精品无码一区二区三区| 欧美日韩1234| 精品无码欧美三级| 日韩偷拍一区二区三区| 免费试看60秒| 亚洲中文字幕在线视频一区二区| 日本αv| 性影在线视频| 人妻一区视频| 免费精品福利在线观看|