算法Go语言描述📌algorithm📌sort3.go
package algorithm
/*
稳定:冒泡、插入、归并
不稳定:选择排序、希尔排序、堆排序、快速排序
小规模数据使用插入排序性能最优,大规模数据一般选用分治策略的排序算法(快速排序平均性能最优,归并排序可满足稳定性要求)。
为避免快速排序划分极度不均导致性能退化,常用堆排版作为后备算法。
对于链表排序,所有需要用到非邻位交换的排序算法都不适用,可用插入、归并。
*/
type ListNode struct {
Val int
Next *ListNode
}
func InsertionSortList(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
dummy := &ListNode{Next: head}
l := head
for r := l.Next; r != nil; r = l.Next {
if r.Val < l.Val {
pre := dummy
for pre.Next.Val <= r.Val {
pre = pre.Next
}
l.Next = r.Next
r.Next = pre.Next
pre.Next = r
} else {
l = l.Next
}
}
return dummy.Next
}
func mergeList(l, r *ListNode) *ListNode {
dummy := &ListNode{}
tail := dummy
for l != nil && r != nil {
if r.Val < l.Val {
tail.Next = r
r = r.Next
} else {
tail.Next = l
l = l.Next
}
tail = tail.Next
}
if l == nil {
tail.Next = r
} else {
tail.Next = l
}
return dummy.Next
}
func MergeSortList1(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
slow, fast := head, head.Next
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
}
mid := slow.Next
slow.Next = nil
l := MergeSortList1(head)
r := MergeSortList1(mid)
return mergeList(l, r)
}
// 指定位置剪断链表并返回后半部分
func cutList(node *ListNode, step int) *ListNode {
for step > 1 && node != nil {
step--
node = node.Next
}
if node == nil {
return nil
}
right := node.Next
node.Next = nil //剪断
return right
}
func MergeSortList2(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
n := 2 //链表长度
for cur := head.Next.Next; cur != nil; cur = cur.Next {
n++
}
dummy := &ListNode{Next: head}
for step := 1; step < n; step <<= 1 {
tail := dummy
cur := dummy.Next
for cur != nil {
left := cur
right := cutList(left, step)
cur = cutList(right, step)
for left != nil && right != nil {
if right.Val < left.Val {
tail.Next = right
right = right.Next
} else {
tail.Next = left
left = left.Next
}
tail = tail.Next
}
if left == nil {
tail.Next = right
} else {
tail.Next = left
}
for tail.Next != nil {
tail = tail.Next
}
}
}
return dummy.Next
}