链表反转 - 链表排序 算法

本文介绍了如何通过链表操作实现链表反转和归并排序,利用快慢指针拆分链表,并展示了详细代码实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链表反转:

  • 想象有1个新链表,每次从旧链表取出一个元素,然后插入到新链表的头部

链表排序:

  • 先将链表拆分为2个子链表
    • 使用快慢指针,快指针每次走2步,当快指针走到尾部时,慢指针即在中间位置
  • 对2个子链表递归排序,返回2个有序的子链表
  • 合并2个有序子链表
package main

import (
	"fmt"
)

type node struct {
	next  *node
	value int
}

func newNode(x int) *node {
	return &node{
		next:  nil,
		value: x,
	}
}

func printList(head *node) { //打印链表
	if head == nil {
		return
	}

	for head != nil {
		fmt.Print(head.value, "->")
		head = head.next
	}
	fmt.Println("nil")
}

func buildList(datas []int) *node { //基于数组创建链表
	if len(datas) == 0 {
		return nil
	}

	head := newNode(datas[0])
	curr := head
	for i := 1; i < len(datas); i++ {
		nextnode := newNode(datas[i])
		curr.next = nextnode
		curr = nextnode
	}
	return head
}

func reverse(head *node) (newhead *node) { //反转链表
	for curr := head; curr != nil; {
		next := curr.next

		curr.next = newhead //头部插入新链表
		newhead = curr

		curr = next
	}
	return
}

func sortList(head *node) (newhead *node) { //链表排序
	if head == nil || head.next == nil { //只有1个node,不用排序
		newhead = head
		return
	}

	/* 找到中点位置,分成2个子链表,做链表的归并排序 */
	head1, head2 := splitList(head)
	sortHead1 := sortList(head1) //对两个子链表分别排序
	sortHead2 := sortList(head2)

	if sortHead1.value < sortHead2.value { //先确定新链表的头结点
		newhead = sortHead1
		sortHead1 = sortHead1.next
		newhead.next = nil
	} else {
		newhead = sortHead2
		sortHead2 = sortHead2.next
		newhead.next = nil
	}

	curr := newhead
	for sortHead1 != nil && sortHead2 != nil { //同时遍历2个子链表
		if sortHead1.value < sortHead2.value {
			curr.next = sortHead1
			sortHead1 = sortHead1.next

		} else {
			curr.next = sortHead2
			sortHead2 = sortHead2.next
		}

		curr = curr.next
		curr.next = nil
	}

	if sortHead1 != nil {
		curr.next = sortHead1
	}
	if sortHead2 != nil {
		curr.next = sortHead2
	}
	return
}

func splitList(head *node) (head1, head2 *node) { //拆分链表
	head1 = head

	if head == nil || head.next == nil { //只有1个结点
		return
	} else if head.next.next == nil { //只有2个结点,一边一个
		head2 = head.next
		head1.next = nil
		return
	}

	slow, fast := head, head
	for fast != nil && fast.next != nil { //快慢指针
		slow = slow.next
		fast = fast.next.next
	}

	head2 = slow.next //慢指针后面的部分,作为第2个链表
	slow.next = nil
	return
}

func main() {

	testCase := 0
	switch testCase {
	case 0:
		head := buildList([]int{5, 6, 7, 8, 9, 10, 1, 2, 3, 4})
		printList(reverse(head))

	case 1:
		head := buildList([]int{5, 6, 7, 8, 9, 10, 1, 2, 3, 4})
		head1, head2 := splitList(head)
		printList(head1)
		printList(head2)

	case 2:
		head := buildList([]int{5, 6, 7, 8, 9, 10, 1, 2, 3, 4})
		printList(sortList(head))
	}

	fmt.Println("Hello World")
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值