链表实现快排和归并
题目连接:https://leetcode.cn/problems/sort-list/
快排(使用快排容易超时,建议使用归并排序)
func main(){ head:=&ListNode{} end:=head aaa:=0 for i:=0;i<6;i++{ if i%2==0{ aaa=i }else{ aaa=-1*i } tmp:=&ListNode{ Val: aaa, Next: nil, } end.Next=tmp end=tmp } quicksort(head.Next,end) head=head.Next for head!=nil{ fmt.Printf("%v ",head.Val) head=head.Next } } type ListNode struct{ Val int Next *ListNode } func quicksort(head,end *ListNode){ if head == nil || head == end{ return } //找基准元素 le , ri := head, head.Next base := le.Val for ri != nil{ //从右边开始处理,将比base小的元素交换到右边 if ri.Val < base{ //不能取等号 le = le.Next le.Val , ri.Val = ri.Val,le.Val } ri = ri.Next } head.Val , le.Val = le.Val,head.Val //[head,le],[le.Next,end] quicksort(head,le) quicksort(le.Next,end) }
归并
type ListNode struct{ Val int Next *ListNode } func main(){ head:=&ListNode{} end:=head aaa:=0 for i:=0;i<6;i++{ if i%2==0{ aaa=i }else{ aaa=-1*i } tmp:=&ListNode{ Val: aaa, Next: nil, } end.Next=tmp end=tmp } h:=sortList(head.Next) for h!=nil{ fmt.Printf("%v ",h.Val) h=h.Next } } func sortList(head *ListNode) *ListNode { if head == nil || head.Next == nil { // 递归的出口,不用排序 直接返回 return head } slow, fast := head, head // 快慢指针将链表对半分 var preSlow *ListNode // 保存slow的前一个结点 for fast != nil && fast.Next != nil { preSlow = slow slow = slow.Next // 慢指针走一步 fast = fast.Next.Next // 快指针走两步 } preSlow.Next = nil // 断开,分成两链 le := sortList(head) // 已排序的左链 ri := sortList(slow) // 已排序的右链 return mergeList(le, ri) // 合并已排序的左右链,一层层向上返回 } func mergeList(le, ri *ListNode) *ListNode { newHead := &ListNode{Val: 0} // 虚拟头结点 end := newHead // 合并后的尾结点,这里使用尾插法合并链表 for le != nil && ri != nil { // le ri 都存在 if le.Val < ri.Val { // le值较小 end.Next = le // end.Next指向le le = le.Next // 考察le的下一个结点 } else { end.Next = ri ri = ri.Next } end = end.Next // end.Next确定了,尾指针推进 } if le != nil { // le存在,ri不存在,让end.Next指向le end.Next = le } if ri != nil { end.Next = ri } return newHead.Next // 真实头结点 }
等风起的那一天,我已准备好一切