049_排序链表

知识点:归并排序、链表

LeetCode第一百四十八题:https://leetcode-cn.com/problems/sort-list/submissions/

语言:GoLang

func sortList(head *ListNode) *ListNode {
	length := 0
	p := head
	for p != nil {
		p = p.Next
		length++
	}
	if length < 2 {
		return head
	}

	node := &ListNode{0, head}

	for slen := 1; slen < length; slen *= 2 {
		pre1, pre2 := node, node
		for i := 1; i <= length; i += 2 * slen {
			pre2 = pre1
			for k := 1; k <= slen && pre2.Next != nil; k++ {
				pre2 = pre2.Next
			}

			pre1 = merge(slen, pre1, pre2)
		}
	}

	return node.Next
}

// 思路简单,细节麻烦
func merge(length int, pre1 *ListNode, pre2 *ListNode) *ListNode {
	node1 := pre1.Next
	node2 := pre2.Next

	step1, step2 := 0, 0
	for {
		if node1 == nil {
			pre1.Next = pre2.Next
			for pre1 != nil && step2 < length {
				pre1 = pre1.Next
				step2++
			}
			return pre1
		}
		if node2 == nil {
			return pre1
		}

		if node1.Val > node2.Val {
			pre1.Next = node2
			pre1 = pre1.Next

			node2 = node2.Next
			pre2.Next = node2
			step2++

			pre1.Next = node1
		} else {
			pre1 = node1
			node1 = node1.Next
			step1++
		}

		if step1 == length {
			for step2 < length {
				pre1.Next = node2
				pre1 = pre1.Next

				pre2 = node2
				node2 = node2.Next
				step2++

				if node2 == nil {
					return pre1
				}
			}
			break
		}
		if step2 == length {
			// 如果第二段已经结束,那么就将第一段的pre1移动至本段末端
			for pre1 != nil && step1 < length {
				pre1 = pre1.Next
				step1++
			}

			break
		}
	}

	return pre1
}
posted @ 2020-04-07 19:57  Cenyol  阅读(76)  评论(0)    收藏  举报