链表反转:
- 想象有1个新链表,每次从旧链表取出一个元素,然后插入到新链表的头部
链表排序:
- 先将链表拆分为2个子链表
- 使用快慢指针,快指针每次走2步,当快指针走到尾部时,慢指针即在中间位置
- 对2个子链表递归排序,返回2个有序的子链表
- 合并2个有序子链表
package main
import (
"fmt"
)
type node struct {
next *node
value int
}
func newNode(x int) *node {
return &node{
next: nil,
value: x,
}
}
func printList(head *node) { //打印链表
if head == nil {
return
}
for head != nil {
fmt.Print(head.value, "->")
head = head.next
}
fmt.Println("nil")
}
func buildList(datas []int) *node { //基于数组创建链表
if len(datas) == 0 {
return nil
}
head := newNode(datas[0])
curr := head
for i := 1; i < len(datas); i++ {
nextnode := newNode(datas[i])
curr.next = nextnode
curr = nextnode
}
return head
}
func reverse(head *node) (newhead *node) { //反转链表
for curr := head; curr != nil; {
next := curr.next
curr.next = newhead //头部插入新链表
newhead = curr
curr = next
}
return
}
func sortList(head *node) (newhead *node) { //链表排序
if head == nil || head.next == nil { //只有1个node,不用排序
newhead = head
return
}
/* 找到中点位置,分成2个子链表,做链表的归并排序 */
head1, head2 := splitList(head)
sortHead1 := sortList(head1) //对两个子链表分别排序
sortHead2 := sortList(head2)
if sortHead1.value < sortHead2.value { //先确定新链表的头结点
newhead = sortHead1
sortHead1 = sortHead1.next
newhead.next = nil
} else {
newhead = sortHead2
sortHead2 = sortHead2.next
newhead.next = nil
}
curr := newhead
for sortHead1 != nil && sortHead2 != nil { //同时遍历2个子链表
if sortHead1.value < sortHead2.value {
curr.next = sortHead1
sortHead1 = sortHead1.next
} else {
curr.next = sortHead2
sortHead2 = sortHead2.next
}
curr = curr.next
curr.next = nil
}
if sortHead1 != nil {
curr.next = sortHead1
}
if sortHead2 != nil {
curr.next = sortHead2
}
return
}
func splitList(head *node) (head1, head2 *node) { //拆分链表
head1 = head
if head == nil || head.next == nil { //只有1个结点
return
} else if head.next.next == nil { //只有2个结点,一边一个
head2 = head.next
head1.next = nil
return
}
slow, fast := head, head
for fast != nil && fast.next != nil { //快慢指针
slow = slow.next
fast = fast.next.next
}
head2 = slow.next //慢指针后面的部分,作为第2个链表
slow.next = nil
return
}
func main() {
testCase := 0
switch testCase {
case 0:
head := buildList([]int{5, 6, 7, 8, 9, 10, 1, 2, 3, 4})
printList(reverse(head))
case 1:
head := buildList([]int{5, 6, 7, 8, 9, 10, 1, 2, 3, 4})
head1, head2 := splitList(head)
printList(head1)
printList(head2)
case 2:
head := buildList([]int{5, 6, 7, 8, 9, 10, 1, 2, 3, 4})
printList(sortList(head))
}
fmt.Println("Hello World")
}