Go-环形链表
package main import "fmt" // 环形单向链表 // 特征: 首尾相连 // 实现: 结构体 + 指针 // 1. 构建环形单向链表,类似单向链表,不过head指针存储值,并且链表尾部与头部相连 // 2. 环形单向链表添加节点则需要一个辅助节点 currentNode 指向环形最后一个节点,然后在该节点后面增加节点并将该节点指向头节点 // a. 处理情况:空链表 // 3. 删除节点: 1. 找到该节点的上一个节点,然后判断是否是头节点,然后将上一个节点指向该节点对应的下一个节点 // a. 处理情况: 空链表、链表中只有一个元素 // b. 难点是如果找到想要删除的节点、删除节点对应的上一个节点、删除的节点对象是头节点怎么处理 // Player 定义玩家,环形结构中每个节点对象 type Player struct { No int Name string next *Player } // Game 游戏 type Game struct { // head指向环形单向链表的第一个元素 head *Player // head指向环形单向链表的第最后个元素 tail *Player } func NewGame() *Game { return &Game{} } // AddPlayer 添加玩家 func (g *Game) AddPlayer(p *Player) { // 1. 判断是否是空链表 if g.head == nil { g.head = p g.tail = p // 1个人形成环 p.next = p } else { // 2. 添加到最后 g.tail.next = p // 3. tail指向最后元素 g.tail = p // 4. 最后元素指向初始头节点 p.next = g.head } } // ListPlayer 列出所有玩家 func (g *Game) ListPlayer() { tmp := g.head for { fmt.Println(tmp) tmp = tmp.next if tmp == g.head { break } } } // Play 玩家开始游戏,从某个玩家开始,然后再数多少为,玩家出局 func (g *Game) Play(startNo int, num int) (p *Player) { // 1. 判断链表是否为空 if g.head == nil { fmt.Println("该游戏没有玩家") return nil } // 2. 如果只有一个玩家,则直接出局 if g.head.next == g.head { p = g.head g.head.next = nil g.head = nil g.tail = nil return } // 3. 指定开始玩家 for i := 1; i <= startNo-1; i ++ { g.head, g.tail = g.head.next, g.tail.next } // 4. 指定出局玩家 for i := 1; i <= num-1; i ++ { g.head, g.tail = g.head.next, g.tail.next } // 5. head指向的就是出局玩家 p = g.head // 6. 在单向链表中移除该玩家 g.tail.next = g.head.next g.head = g.tail.next return } func main() { pl2 := Player{ No: 0, Name: "tom", } pl3 := Player{ No: 2, Name: "alex", } pl4 := Player{ No: 3, Name: "xueli", } pl5 := Player{ No: 0, Name: "yang", } g := NewGame() g.AddPlayer(&pl2) g.AddPlayer(&pl3) g.AddPlayer(&pl4) g.AddPlayer(&pl5) g.ListPlayer() fmt.Println("-------------------------") outPlayer := g.Play(3, 10) fmt.Println("出局玩家:", outPlayer.Name) g.ListPlayer() }