链表结构定义如下:
// 链表结点 type SinListNode struct { next *SinListNode val int } // 链表结构 type SinLinkedList struct { head *SinListNode len uint }
实现的操作有:
- 单链表结点的创建
- 获取链表的下一结点
- 获取结点值
- 链表的创建
- 在指定结点后插入结点
- 在指定结点前插入结点
- 在链表头部插入结点
- 在链表尾部插入结点
- 通过索引查找结点
- 删除指定结点
- 链表的打印
- 链表的翻转
- 判断链表是否有环
- 合并两个有序单链表
- 删除倒数第N个结点
- 获取链表的中间结点
代码如下:
package main import "fmt" /* 单链表的实现 */ // 链表结点 type SinListNode struct { next *SinListNode val int } // 链表结构 type SinLinkedList struct { head *SinListNode len uint } // 创建结点 func NewListNode(v interface{}) *SinListNode { return &SinListNode{nil, v} } // 获取链表下一个节点 func (this *SinListNode) GetNext() *SinListNode { return this.next } // 获取节点值 func (this *SinListNode) GetValue() int { return this.val } // 创建链表 func NewLinkedList() *SinLinkedList { return &SinLinkedList{NewListNode(0), 0} } // 在指定节点后面插入节点 func (this *SinLinkedList) InsertAffter(p *SinListNode, v int) bool { if nil == p { return false } // 创建一个新节点 newNode, oldNext := NewListNode(v), p.next // 新节点插入到指定节点后,原节点的下一节点插入到新节点的下一节点 p.next, newNode.next = newNode, oldNext this.len++ return true } // 在某个节点前面插入节点 func (this *SinLinkedList) InsertBefore(p *SinListNode, v int) bool { if nil == p || p == this.head { return false } cur := this.head.next // 记录当前节点 pre := this.head // 记录前缀节点 // 查找p的前缀节点 for cur != nil { if cur == p { break } pre = cur cur = cur.next } if cur == nil { return false } newNode := NewListNode(v) pre.next = newNode // 前缀节点指向新节点 newNode.next = cur // 新节点指向原来的节点P this.len++ return true } // 在链表头部插入节点 func (this *SinLinkedList) InsertToHead(v int) bool { return this.InsertAffter(this.head, v) } // 在链表尾部插入节点 func (this *SinLinkedList) InsertToTail(v int) bool { cur := this.head // 查找尾节点 for cur.next != nil { cur = cur.next } return this.InsertAffter(cur, v) } // 通过索引查找节点 func (this *SinLinkedList) FindByIndex(idx uint) *SinListNode { if idx >= this.len { return nil } cur := this.head.next // 移动节点值idx位置 var i uint = 0 for ; i < idx; i++ { cur = cur.next } return cur } // 删除指定结点 func (this *SinLinkedList) DeleteNode(p *SinListNode) bool { if p == nil { return false } cur := this.head.next pre := this.head // 查找p的前驱节点 for cur != nil { if cur == p { break } pre = cur cur = cur.next } // 找不到p节点 if cur == nil { return false } // p的前驱节点指向p的后继节点 pre.next = p.next p = nil // 释放p节点 this.len-- return true } // 打印链表 func (this *SinLinkedList) Print() { cur := this.head.next format := "" for cur != nil { format += fmt.Sprintf("%+v", cur.GetValue()) if cur != nil { format += "->" } } fmt.Println(format) } // 单链表翻转,时间复杂度O(n) func (this *SinLinkedList)Reverse() { if this.head == nil || this.head.next == nil || this.head.next.next == nil { return } var pre *SinListNode = nil cur := this.head.next for cur != nil { tmp := cur.next cur.next = pre pre, cur = cur, tmp } this.head.next = pre } // 快慢指针判断链表是否有环 func (this *SinLinkedList) HasCycle() bool { if this.head != nil { slow := this.head fast := this.head if fast != nil && fast.next != nil{ slow = slow.next // 慢指针一次移动一个节点 fast = fast.next.next // 快指针一次移动两个节点 if slow == fast { // 指针相遇证明有环 return true } } } return false } // 合并两个有序单链表 func MergeSortedList(l1, l2 *SinLinkedList) *SinLinkedList { // 链表1为空直接返回链表2 if l1 == nil || l1.head == nil || l1.head.next == nil { return l2 } // 链表2为空直接返回链表1 if l2 == nil || l2.head == nil || l2.head.next == nil { return l1 } l := &SinLinkedList{head:&SinListNode{}} cur := l.head // 使用双指针思想进行合并 curl1 := l1.head.next curl2 := l2.head.next for curl1 != nil && curl2 != nil { if curl1.GetValue() > curl2.GetValue() { cur.next = curl2 curl2 = curl2.next }else { cur.next = curl1 curl1 = curl1.next } cur = cur.next } if curl1 != nil { cur.next = curl1 }else if curl2!= nil { cur.next = curl2 } return l } // 删除倒数第N个节点 func (this *SinLinkedList) DeleteBottomN(n int) { if n <= 0 || this.head == nil || this.head.next == nil { return } fast := this.head // 查找第N个节点 for i := 1; i <= n && fast!= nil; i++ { fast = fast.next } if fast == nil { return } slow := this.head for fast.next != nil { slow = slow.next fast = fast.next } slow.next = slow.next.next } // 获取链表的中间节点 func (this *SinLinkedList) FindMiddleNode() *SinListNode { if nil == this.head || this.head.next == nil { return nil } // 链表只有一个元素则直接返回该节点 if this.head.next.next == nil { return this.head.next } slow, fast := this.head, this.head // 使用快慢指针, 快指针移动两个节点,慢指针移动一个节点,当快指针遍历结束,那么慢指针指向的节点为中间节点 for fast != nil && fast.next != nil { slow = slow.next fast = fast.next.next } return slow }