# 三分链表

将单向链表按某值划分成左边小、中间相等、右边大的形式,可以使用下面 两种方式:
- 把链表放入数组里, 在数组上做partition
- 分成小、中、大三部分,再把各个部分之间串起来
# 算法流程

# 代码实现
type ListNode struct {
Val int
Next *ListNode
}
func threePart(head *ListNode, x int) *ListNode {
if head == nil || head.Next == nil {
return head
}
var lessHead, lessTail *ListNode // 小于区域
var equalHead, equalTail *ListNode // 等于区域
var biggerHead, biggerTail *ListNode // 大于区域
var nextTmp *ListNode // 记录每次下一个节点
cur := head
for cur != nil {
nextTmp = cur.Next
// 将当前节点与后续的节点断开连接
cur.Next = nil
// 小于区域
if cur.Val < x && lessHead == nil && lessTail == nil {
lessHead, lessTail = cur, cur
} else if cur.Val < x && lessHead != nil && lessTail != nil {
lessTail.Next = cur
lessTail = cur
}
// 等于区
if cur.Val == x && equalHead == nil && equalTail == nil {
equalHead, equalTail = cur, cur
} else if cur.Val == x && equalHead != nil && equalTail != nil {
equalTail.Next = cur
equalTail = cur
}
// 大于区
if cur.Val > x && biggerHead == nil && biggerTail == nil {
biggerHead, biggerTail = cur, cur
} else if cur.Val > x && biggerHead != nil && biggerTail != nil {
biggerTail.Next = cur
biggerTail = cur
}
// 到下一个节点
cur = nextTmp
}
if lessHead != nil && lessTail != nil {
lessTail.Next = equalHead
lessTail = equalTail
}
if lessTail != nil {
lessTail.Next = biggerHead
}
if lessHead != nil {
return lessHead
} else if equalHead != nil {
return equalHead
} else {
return biggerHead
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# 拓展题目
// 类似力扣题目:86. 分隔链表
// 题目连接:https://leetcode.cn/problems/partition-list/description/
func partition(head *ListNode, x int) *ListNode {
if head == nil || head.Next == nil {
return head
}
var lessHead, lessTail *ListNode // 小于区域
var equalBiggerHead, equalBiggerTail *ListNode // 大于等于区域
var nextTmp *ListNode // 记录每次下一个节点
cur := head
for cur != nil {
nextTmp = cur.Next
// 将当前节点与后续的节点断开连接
cur.Next = nil
// 小于区域
if cur.Val < x && lessHead == nil && lessTail == nil {
lessHead, lessTail = cur, cur
} else if cur.Val < x && lessHead != nil && lessTail != nil {
lessTail.Next = cur
lessTail = cur
}
// 等于区
if cur.Val >= x && equalBiggerHead == nil && equalBiggerTail == nil {
equalBiggerHead, equalBiggerTail = cur, cur
} else if cur.Val >= x && equalBiggerHead != nil && equalBiggerTail != nil {
equalBiggerTail.Next = cur
equalBiggerTail = cur
}
// 到下一个节点
cur = nextTmp
}
if lessHead != nil && lessTail != nil {
lessTail.Next = equalBiggerHead
}
if lessHead != nil {
return lessHead
}
return equalBiggerHead
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40