合并两个以及n个链表(生序)

这篇博客介绍了如何合并多个已排序的链表。首先通过双指针比较尾插法合并两个链表,然后利用分治策略,将链表两两合并,最终整合成一个有序链表。代码中提供了创建链表、反转链表、合并链表等函数的实现,并给出了一个示例来演示整个过程。

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)
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Steps-of-time

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值