1.根据要求,判别合并之后也需要生序,两个链表,直接双指针比较尾插法即可,(判断极端条件即可)
2.n个链表,采用分治,进行两两排序合并,最后在整合成一条链表即可。
3.代码如下:
package main
import (
"fmt"
)
type Node struct {
Val interface{}
Next *Node
}
type Link struct {
Head, Tail *Node
}
// create
func (l *Link) CreateLink(val interface{}) {
node := &Node{Val: val, Next: nil}
if l.Head == nil {
l.Head = node
l.Tail = node
}
l.Tail.Next = node
l.Tail = node
}
// 反转链表,拆节点,使用头插法冲洗构建链表
func (l *Link) RevolveLink() {
if l.Head == nil {
return
}
// 拆出头节点
t := l.Head.Next
l.Head.Next = nil
l.Tail = l.Head
for t != nil {
m := t
t = t.Next
m.Next = l.Head
l.Head = m
}
}
// 合并N个已经排序的链表,都是按照生序,分治法,两两合并
func MergerLink(linkArray []*Node) *Node {
if len(linkArray) == 0 {
return nil
}
if len(linkArray) == 1 {
return linkArray[0]
}
if len(linkArray) == 2 {
return MergeTwoLink(linkArray[0], linkArray[1])
}
mid := len(linkArray) >> 1
// left,right
// 两两合并,最后合并成一个
left := make([]*Node, mid)
right := make([]*Node, len(linkArray)-mid)
copy(left, linkArray[:mid])
copy(right, linkArray[mid+1:])
return MergeTwoLink(MergerLink(left), MergerLink(right))
}
// 合并两个排序递归
func MergeTwoLink(first, second *Node) *Node {
if first == nil {
return second
}
if second == nil {
return first
}
var head *Node = nil
if first.Val.(int) < second.Val.(int) {
head = first
head.Next = MergeTwoLink(head.Next, second)
} else {
head = second
head.Next = MergeTwoLink(first, head.Next)
}
return head
}
// 合并两个已经排序的链表
func Merge(first, second *Link) *Node {
// 考虑空链表情况
if first == nil && second == nil {
return nil
}
if first == nil {
return second.Head
}
if second == nil {
return first.Head
}
var HeadLink, TailLink *Node = nil, nil
f := first.Head
s := second.Head
for f != nil && s != nil {
if f.Val.(int) <= s.Val.(int) {
if HeadLink == nil {
HeadLink = f
TailLink = HeadLink
} else {
TailLink.Next = f
TailLink = f
}
f = f.Next
} else {
if HeadLink == nil {
HeadLink = s
TailLink = HeadLink
} else {
TailLink.Next = s
TailLink = s
}
s = s.Next
}
}
// 剩余的直接续在新链表后面
if f == nil {
TailLink = s
}
if s == nil {
TailLink = f
}
return HeadLink
}
func (l *Link) Show() {
for h := l.Head; h != nil; h = h.Next {
fmt.Println("->", h.Val, "-", l.Head.Val, "-", l.Tail.Val)
}
}
func main() {
first := &Link{nil, nil}
second := &Link{nil, nil}
third := &Link{nil, nil}
fourd := &Link{nil, nil}
for i := 0; i < 20; i++ {
if i%2 == 0 {
first.CreateLink(i)
}
if i%4 == 0 {
second.CreateLink(i)
}
if i%5 == 0 {
third.CreateLink(i)
}
if i%8 == 0 {
fourd.CreateLink(i)
}
}
first.Show()
second.Show()
third.Show()
fourd.Show()
ListArray := make([]*Link, 0)
ListArray = append(ListArray, first, second, third, fourd)
NodeList := make([]*Node, 0)
NodeList = append(NodeList, first.Head, second.Head, third.Head, fourd.Head)
root := MergerLink(NodeList)
// root := MergeTwoLink(first.Head, second.Head)
fmt.Println("Merge link...")
for ; root != nil; root = root.Next {
fmt.Println(root.Val)
}
}
这篇博客介绍了如何合并多个已排序的链表。首先通过双指针比较尾插法合并两个链表,然后利用分治策略,将链表两两合并,最终整合成一个有序链表。代码中提供了创建链表、反转链表、合并链表等函数的实现,并给出了一个示例来演示整个过程。
4338

被折叠的 条评论
为什么被折叠?



