Golang单链表反转(迭代与栈方式)
代码如下(代码大意表达,没有考虑和处理各种空等意外情况):
package main import ( "strings" "github.com/golang-collections/collections/stack" ) type node struct { i int next *node } var linkList *node func makeList() { // 创建一个单链表: 0->1->2->3->4->5->6->7->8->9 // 这里依次遍历到尾部追加,也可以使用一个尾指针来指示快速添加 linkList = &node{i: 0} for i := 1; i < 10; i++ { linkList := linkList for { if linkList.next == nil { linkList.next = &node{i: i} break } linkList = linkList.next } } } func traverse() { // 遍历单链表 iter := linkList for { if iter != nil { if iter.next == nil { print(iter.i) } else { print(iter.i, "->") } iter = iter.next } else { break } } println() } func reverse() { // 迭代反转链表 var next *node // 反转后所应该指向的下一个节点,默认初始化为空 for { // 首先保存原链表反转前的下一个节点 tmp := linkList.next // 反转后所应该指向的下一个节点 linkList.next = next // 上面两步对于一个节点来说先保存其旧next,然后用新next覆盖 // 当前节点已反转,它应当被下一个待反转节点next指向,这里把它覆盖存入next中 next = linkList // tmp来自每个节点的next,如果tmp为空,说明已经反转到最后一个节点了 if tmp == nil { break } else { // tmp不为空,将当前节点指针linkList推进到下一个节点,即推进到tmp(反转工作循环前两步已经完成) linkList = tmp } } } func reverseByStack() { // 初始化一个栈 s := stack.New() for { if linkList != nil { // 每个节点依次压栈 s.Push(linkList) linkList = linkList.next } else { break } } // 弹栈,获取最后一个栈元素 iter := s.Pop().(*node) // 保存最后一个元素(反正后第一个元素)指针 linkList = iter for { // 栈不空时,说明所有节点未处理完 if s.Len() > 0 { // 依次出栈 iter.next = s.Pop().(*node) // 上一个出栈节点指向当前出栈节点 iter = iter.next } else { break } } iter.next = nil } func m() { makeList() traverse() reverse() traverse() reverse() traverse() reverse() traverse() } func n() { makeList() traverse() reverseByStack() traverse() reverseByStack() traverse() reverseByStack() traverse() } func main() { m() println(strings.Repeat("=", 28)) n() }
对于栈方式反转示意图如下
程序运行结果: