golang的鏈表結(jié)構(gòu)簡單,如下
type ListNode struct {
Val int //節(jié)點(diǎn)值
Next *ListNode //存儲著下一個(gè)節(jié)點(diǎn)的地址网棍,用指針表示
}
不廢話兼蜈,先定義并初始化一個(gè)單鏈表
func main() {
head := new(ListNode)
head.Val = 1
ln2 := new(ListNode)
ln2.Val = 2
ln3 := new(ListNode)
ln3.Val = 3
ln4 := new(ListNode)
ln4.Val = 4
ln5 := new(ListNode)
ln5.Val = 5
head.Next = ln2
ln2.Next = ln3
ln3.Next = ln4
ln4.Next = ln5
pre := reverse(head)
}
然后,開始介紹我所理解的方法
方法一:新建一個(gè)鏈表(只有頭結(jié)點(diǎn))序宦,然后遍歷需要翻轉(zhuǎn)的鏈表睁壁,逐個(gè)插入到新鏈表中即可,最后新鏈表就是原鏈表的翻轉(zhuǎn)鏈表互捌,如圖
圖例解釋:
1潘明、dummy是只有頭結(jié)點(diǎn)的新鏈表,或者說dummy就是新鏈表的頭結(jié)點(diǎn)
2秕噪、pCur是要插入到新鏈表的節(jié)點(diǎn)钳降。
3、定義一個(gè)pNex作為一個(gè)中轉(zhuǎn)變量腌巾,臨時(shí)保存的pCur的next遂填,也就是下一個(gè)要插入新鏈表的節(jié)點(diǎn)信息铲觉。
4、將當(dāng)前dummy的指向(dummy指向nil)賦值給當(dāng)前要插入新鏈表中的節(jié)點(diǎn)(原來指向pNex,賦值后也指向nil)
5吓坚、調(diào)整dummy的指向撵幽,讓指針指向當(dāng)前要插入的節(jié)點(diǎn)pCur
經(jīng)過4、5 新鏈表中就形成了一個(gè) dummy->pCur->nil的鏈表
6礁击、需要循環(huán)原鏈表 盐杂,則要保持原鏈表中pCur != nil ,所以客税,要將3中的pNex賦值給pCur繼續(xù)進(jìn)行循環(huán)(即重復(fù)3~6步)况褪,直到pCur沒有值了方可罷休
此時(shí),上代碼
func reverse(head *ListNode) *ListNode {
//簡稱更耻,頭插法
newList := new(ListNode) //步驟1
pCur := head //步驟2
for pCur != nil {
pNex := pCur.Next //步驟3
pCur.Next = newList.Next //步驟4
newList.Next = pCur //步驟5
pCur = pNex //步驟6
}
return newList.Next //循環(huán)完畢测垛,返回原鏈表的翻轉(zhuǎn)鏈表
}
方法二 :就地翻轉(zhuǎn)
直接上圖解釋
1、dummy是頭結(jié)點(diǎn)秧均,指向首元節(jié)點(diǎn)prev
2食侮、pCur是待翻轉(zhuǎn)的節(jié)點(diǎn)
3、將pCur的指向賦值給prev(這樣做目胡,就可以吧prev到pCur的指向斷開)
4锯七、將dummy的指向賦值給pCur(這樣做,就可以把pCur指向下一個(gè)節(jié)點(diǎn)3的路斷開誉己,并讓pCur重新指向prev)
經(jīng)過3眉尸、4 就可以把prev,pCur進(jìn)行位置翻轉(zhuǎn)
5巨双、此時(shí)噪猾,再把dummy的指針指向pCur,就可以形成了:頭->2->1 ....的鏈表
6筑累、需要循環(huán)原鏈表 袱蜡,則要保持原鏈表中pCur != nil ,所以慢宗,需要pCur = prev.Next (即重復(fù)3~6步)坪蚁,直到pCur沒有值了方可罷休
代碼就不上了,大同小異
最后镜沽,上個(gè)打印的方法敏晤,因?yàn)榇鎯χ苯哟蛴【褪堑刂妨耍枰阎嫡故境鰜聿胖庇^
func printNode(head *ListNode) {
for head != nil {
fmt.Println(head.Val)
head = head.Next
}
}