單鏈表是一種經(jīng)典的數(shù)據(jù)結(jié)構(gòu),它由一系列的節(jié)點(diǎn)組成,每個節(jié)點(diǎn)都包含一個數(shù)據(jù)元素和指向下一個節(jié)點(diǎn)的指針。由于鏈表的節(jié)點(diǎn)存在順序關(guān)系,因此可以使用逆序操作將單鏈表中節(jié)點(diǎn)的順序顛倒過來。在Java中,單鏈表的逆序操作一般有兩種實(shí)現(xiàn)方式,即遞歸和循環(huán)。
首先,我們來介紹遞歸方式的單鏈表逆序。遞歸是一種非常優(yōu)雅、簡潔的算法實(shí)現(xiàn)方式,它在Java中的表現(xiàn)非常出色。遞歸的實(shí)現(xiàn)方式是,將單鏈表分成頭節(jié)點(diǎn)和剩余節(jié)點(diǎn)兩部分,將剩余鏈表逆序后再將頭節(jié)點(diǎn)加到末尾。具體的遞歸實(shí)現(xiàn)代碼如下:
public static ListNode reverseListRecursively(ListNode head) { if (head == null || head.next == null) { return head; } ListNode newHead = reverseListRecursively(head.next); head.next.next = head; head.next = null; return newHead; }
上面的代碼將所有節(jié)點(diǎn)都遍歷了一遍,因此時間復(fù)雜度為O(n)。但需要注意的是,遞歸過程使用了系統(tǒng)的棧,因此在單鏈表比較長的情況下會有棧空間不足的風(fēng)險。
其次,我們來介紹循環(huán)方式的單鏈表逆序。循環(huán)方式的實(shí)現(xiàn)思路是,利用三個指針指向三個相鄰的節(jié)點(diǎn),并依次將它們逆序。具體的循環(huán)實(shí)現(xiàn)代碼如下:
public static ListNode reverseListIteratively(ListNode head) { ListNode prev = null; ListNode curr = head; while (curr != null) { ListNode nextTemp = curr.next; curr.next = prev; prev = curr; curr = nextTemp; } return prev; }
上面的代碼只遍歷了一遍單鏈表,因此時間復(fù)雜度也是O(n)。相比于遞歸方式,循環(huán)方式的實(shí)現(xiàn)代碼更加清晰、簡潔,同時也不會出現(xiàn)棧空間不足的問題。