golang链表排序

发布时间:2024-12-23 05:08:41

链表(Linked List)是一种常见的数据结构,它由节点(Node)组成,每个节点分别指向下一个节点,最后一个节点指向空。在golang中,链表排序是一个常见的问题。本文将介绍如何使用golang对链表进行排序。

1. 链表的定义与实现

首先,我们需要定义链表的结构和节点的结构:

type ListNode struct {
    Val  int
    Next *ListNode
}

链表的每个节点都包含一个值(Val)和一个指向下一个节点的指针(Next)。使用Val来存储节点的值,使用Next来指明下一个节点的位置。

接下来,我们可以通过一个数组来创建一个链表:

func CreateLinkedList(arr []int) *ListNode {
    if len(arr) == 0 {
        return nil
    }
    head := &ListNode{}
    cur := head
    for _, v := range arr {
        cur.Next = &ListNode{
            Val: v,
        }
        cur = cur.Next
    }
    return head.Next
}

这个函数接受一个整数数组作为参数,并返回一个链表的头节点。我们通过遍历数组,依次创建节点,然后通过指针将各个节点连接起来。

2. 快速排序算法

快速排序(Quicksort)是一种高效的排序算法。它的基本思想是选择一个基准元素,将数组分成比基准元素小和比基准元素大的两部分,然后对这两部分分别进行递归排序。

在golang中,我们可以使用以下代码实现快速排序:

func QuickSort(arr []int) {
    if len(arr) <= 1 {
        return
    }
    pivot := arr[0]
    left, right := 0, len(arr)-1

    for i := 1; i <= right; {
        if arr[i] > pivot {
            arr[i], arr[right] = arr[right], arr[i]
            right--
        } else {
            arr[i], arr[left] = arr[left], arr[i]
            left++
            i++
        }
    }

    QuickSort(arr[:left])
    QuickSort(arr[left+1:])
}

该函数接受一个整数数组作为参数,并对其进行原地排序。我们选择数组的第一个元素作为基准元素(pivot),然后使用左右指针分别指向数组的首尾。

接着,我们使用一个循环遍历数组,并将比基准元素大的元素交换到右边,比基准元素小的元素交换到左边。这样,数组就被分成了两部分。

最后,我们对这两部分分别进行递归排序,直到数组长度小于等于1。

3. 链表的排序

在golang中,链表的排序可以通过以下代码实现:

func SortLinkedList(head *ListNode) *ListNode {
    if head == nil || head.Next == nil {
        return head
    }
    prev, slow, fast := (*ListNode)(nil), head, head

    for fast != nil && fast.Next != nil {
        prev, slow, fast = slow, slow.Next, fast.Next.Next
    }
    prev.Next = nil

    return MergeLinkedList(SortLinkedList(head), SortLinkedList(slow))
}

func MergeLinkedList(a, b *ListNode) *ListNode {
    if a == nil {
        return b
    }
    if b == nil {
        return a
    }
    if a.Val < b.Val {
        a.Next = MergeLinkedList(a.Next, b)
        return a
    } else {
        b.Next = MergeLinkedList(a, b.Next)
        return b
    }
}

首先,我们判断链表是否为空或只有一个节点,如果是的话,则直接返回该链表。

接着,我们使用快慢指针找到链表的中间节点:快指针每次移动两步,慢指针每次移动一步。当快指针到达链表尾部时,慢指针正好处于链表的中间位置。我们使用prev指针将链表分成两部分。

然后,我们对这两部分分别进行递归排序。

最后,我们通过MergeLinkedList函数将两个有序链表合并成一个有序链表。该函数接受两个有序链表的头节点作为参数,并返回合并后的有序链表的头节点。

通过以上步骤,我们就可以使用golang对链表进行排序了。链表的排序是一个常见且重要的问题,掌握了这个问题的解决方法,对于日常的开发工作和面试提升都会有很大帮助。

相关推荐