單鏈表反轉的分析及實(shí)現 _雙向鏈表
單鏈表反轉的表反表(°□°)分析及實(shí)現
(圖片來(lái)源網(wǎng)絡(luò ),侵刪)基本概念
單鏈表是(shi)分析一種常見(jiàn)的數據結構,由一系列節點(diǎn)組成,及(???)實(shí)每個(gè)節點(diǎn)包含兩部分:數據域和指向下一個(gè)節點(diǎn)的現雙向鏈指針域,反轉單鏈表意味著(zhù)將鏈表中的單鏈節點(diǎn)順序逆置,例如將鏈表1>2>3>4>5反轉為5>4>3>2>1。表反表
創(chuàng )建單鏈表
為了深入理解反轉過(guò)程,分析首先需要創(chuàng )建一個(gè)單鏈表,及實(shí)通常使用一個(gè)節點(diǎn)類(lèi)來(lái)封??裝數據域和指針域:
public clasヾ(′▽?zhuān)??s ListNode { int val;? ListNode next; ListNode(int x) { val = x; }}可以使用?以下方式創(chuàng )建一個(gè)單鏈表:
ListNode head = neヾ(′?`)?w ListNode(1);head.next = new ListNode(2);head.next.next = new ListNode(???3);// ...以此類(lèi)推
單鏈表反轉方法分析
1.ヾ(^-^)ノ 迭代法(三ヽ(′▽?zhuān)?ノ指針?lè )ǎ?/p>(圖片來(lái)源網(wǎng)絡(luò ),現雙向鏈侵刪)??
這種方(fang)法使用三個(gè)指針:pre(前驅節點(diǎn))、cur(當前節點(diǎn))和next(后續節點(diǎn)),核心思想是遍歷鏈表,不斷改變當前節點(diǎn)的指針?lè )较?,使其指向前驅節點(diǎn),具體步驟如下:
初始化??:pre = nulヾ(^-^)ノl,cur = hea(°o°)d
循環(huán)直到cur為null:
next = cur.next // 暫存下一個(gè)節點(diǎn)
cur.next = pre // 改變(bian)當前節點(diǎn)的指針?lè )较?/p>
pre( ?ヮ?) = cur // 移動(dòng)前驅指針
cur = next // 移動(dòng)當前指針
返回新的頭結點(diǎn)pre
代碼示例(?⊿?):
public ListNode reverseItera??tively(ListNode head) { ListNode pre = null, cur = head; while (cur != null) { ListNode nextTemp = cur.next; cur.next = pre; pre = cur; cur = nextTemp; } return pre;}2. 遞歸法
遞歸法利用函數自身調用反轉剩余部分的子鏈表,然后將當前節點(diǎn)連接到反轉后的子鏈表末尾,具(ju)體步驟如下:
如果鏈表為空或只有一個(gè)節點(diǎn),直接返回。
否則,遞歸調用反??轉除第一個(gè)節點(diǎn)外的子鏈表。
將第一個(gè)節點(diǎn)接到反轉后的子鏈表的頭部。
代碼示例:
public ListNode(/ω\) reverseRecu(??ヮ?)?*:???rsively(ListNode head) { if (head == null || head.next == null) return head; Lis(???)tNode p = reverseRecursively(head.next); head.next.next = head; head.next = null; return p;}3. 頭(tou)插法
頭插法通(tong)過(guò)改變原鏈表的節點(diǎn)指向來(lái)實(shí)現反轉,具體步驟如下:
從鏈表頭開(kāi)始,將每個(gè)ヾ(′?`)?節點(diǎn)依次插入到新鏈表的頭部。
同時(shí)改變原節點(diǎn)的指針?lè )较颉?/p>
直到所有節點(diǎn)都被重新插入。
public ListNode reverseByHeadInsert(ListNode head) { ListNode newHead = new ListNode(0); ListNode p = head; while (p !=ヽ(′▽?zhuān)?/ null) { ListNode nextTeヽ(′ー`)ノmp = p.next; p.next = newHead.next; newHead.next = p; p = nextTemp; } return newHead.ne??xt;}性能分析
時(shí)間復雜度:以上三種方法的時(shí)間復雜度均為O(N),其中N為鏈表長(cháng)度。
空間復雜度:迭代法的空間復雜度為O(1);遞歸法的空間復雜度取(O_O)決于遞歸深度,最壞情況下為O(N);頭插法的空間復雜度也為O(1)(不考慮新建節點(diǎn)帶來(lái)的額外空間)。
相關(guān)問(wèn)答FAQs
問(wèn)1:為什么需要反轉單鏈表?
答??:在實(shí)際應用中,反轉單鏈表可以用于多種場(chǎng)景,如回文檢測、數據流逆序處理等,掌握鏈表反轉技巧有助于加深對鏈表操作的理解,提高數據結構處理能力。
問(wèn)2:如何判斷一個(gè)單鏈表是否是回文?
答:一種方法是先將鏈表反轉(zhuan),然后逐個(gè)比(bi)較原鏈表和反轉后鏈表的節點(diǎn)值,如果完全相同,則該鏈表是回文結構,另一??種更高效的方法是使用雙指針??技術(shù),快慢指針定位到鏈表中央,反轉后半(╬?益?)部分鏈表,再逐一比較前后半部分是否對稱(chēng)。
下面是一個(gè)介???紹,對比了單鏈表和雙向鏈表在反轉操作的分析和實(shí)現上的不同:
| 特性/操作 | 單鏈表反轉 | 雙向鏈表反轉 |
| 節點(diǎn)結構 | 只有next指針,指向下一個(gè)節點(diǎn) | 同時(shí)有next和prev指針,分別指向下一個(gè)和前一個(gè)節點(diǎn) |
| 實(shí)現復雜性 | 較復雜,需??要額外存儲前一個(gè)節點(diǎn) | 較簡(jiǎn)單,直接使用prev指針 |
| 代碼實(shí)現 | ||
步驟1 | 保存當前節點(diǎn)的下一個(gè)節點(diǎn) | 臨時(shí)保存當前節點(diǎn)的下一個(gè)節點(diǎn) |
| 步驟2 | 當前節點(diǎn)的next指針指向??前一個(gè)節點(diǎn) | 當前節點(diǎn)的pre(???)v指針指向下一個(gè)節點(diǎn)(反轉) |
| 步驟3 | 更新前一個(gè)節點(diǎn)為當前(qian)節點(diǎn) | 更新下一個(gè)節點(diǎn)為當前節點(diǎn) |
| 步驟4 | 移動(dòng)到下一個(gè)節點(diǎn)(最初保存在步驟1) | 移動(dòng)到下一個(gè)節點(diǎn)(最初保存在步驟1) |
循環(huán)條件 | 當前節點(diǎn)不為null | 當前節點(diǎn)不為null |
| 時(shí)間復雜度 | O(n) | O(n) |
| 空間復雜度 | O(1)??(不需要額外存儲,除了幾個(gè)臨時(shí)變量) | O(1)(不需要額外存儲,除了幾個(gè)臨時(shí)變量)?? |
| 適用場(chǎng)景 | 適用于只需要單向遍歷的場(chǎng)景 | 適用于需要雙(???)向遍歷的場(chǎng)景,反轉操作更簡(jiǎn)單 |
注意事項 | 需要特別小心指針的更新,以免丟失鏈表?? | 直接操作prev指針,但需要確保不會(huì )違反雙向鏈表的結構 |




