单链表的快速排序

2018-09-23  本文已影响0人  lwj_ow

最近保研成功,没啥事情在看Java,所以处于新学习的状态,也没怎么写博客,不过正好有朋友问到关于链表的快排的问题,所以我也了解了一下,顺便在这里做个记录,同时开个头,以后也要多写点博客了,毕竟这一年都没啥事情.

  1. 简介
    给定一个单链表的头节点,要将该链表排序. 这个问题的解法实际上有很多,这里我主要写一下快排的实现.值得注意的是,我们这里用的是值交换,并不是指针交换,对于单链表问题有时候使用值交换是非常方便的,避免了很多的指针操作.

  2. 思路
    办法实际上不难,我们回忆一下快排的思路,先选取一个key,然后以key为标准,将数组划分为两个子数组,一个子数组的所有值都小于key,另一个子数组的所有值都大于等于key,然后再对这两个子数组重复之前的操作,最终整个数组都排序完成.
    但是我们这里应该怎么办呢,其实思路不算难,我们先选取第一个元素作为key,当然key的选取可能有思路,但这个不是快排的重点,我们接下来保存两个指针,假设一个指针为p,一个指针为q,我们希望p当前指向的值以及在p前面的值都是小于key的,而处于p以及q之间的值都是大于等于key的,因此当q到达链表的尾端时,数组就已经分组完成了,显然这和数组快排的思路是基本一致的.

  3. 具体步骤
    暂时我也不知道有什么工具可以用来画这个图,所以就手画了一哈,但是大概思路是没有问题的,希望大家理解一下.


    image.png
  4. 代码实现
    由于我最近都在看Java,所以为了锻炼一哈Java的代码能力,这里源码用的是Java来实现,代码如下:

public class SingleListQuickSort {
    static class Node
    {
        public int key;
        public Node next;
        public Node(int k) {
            key = k;
            next = null;
        }
        public Node(int k, Node node) {
            key = k;
            next = node;
        }
    }
    Node partition(Node begin, Node end)
    {
        if(begin == end)
            return begin;
        int key = begin.key;
        Node pNode = begin;
        Node qNode = begin.next;
        while(qNode != end)
        {
            if(qNode.key < key)
            {
                pNode = pNode.next;
                int tempKey = pNode.key;
                pNode.key = qNode.key;
                qNode.key = tempKey;
            }
            qNode = qNode.next;
        }
        int temp = begin.key;
        begin.key = pNode.key;
        pNode.key = temp;
        return pNode;
    }
    void quickSort(Node head, Node end)
    {
        if(head != end)
        {
            Node pNode = partition(head, end);
            quickSort(head, pNode);
            quickSort(pNode.next, end);
        }
    }
    void printSingleList(Node head)
    {
        while(head != null)
        {
            System.out.println(head.key);
            head = head.next;
        }
    }
    public static void main(String[] args) {
        Node head = new Node(4);
        Node node = new Node(2);
        Node node2 = new Node(5);
        Node node3 = new Node(3);
        Node node4 = new Node(7);
        Node node5 = new Node(9);
        Node node6 = new Node(0);
        Node node7 = new Node(1);
        head.next = node;
        node.next = node2;
        node2.next = node3;
        node3.next = node4;
        node4.next = node5;
        node5.next = node6;
        node6.next = node7;
        SingleListQuickSort singleListQuickSort = new SingleListQuickSort();
        singleListQuickSort.quickSort(head, null);
        singleListQuickSort.printSingleList(head);
    }
}

经过测试之后,代码也是没有问题的,欢迎各位朋友copy下来测试一下.

总结: 这次的博客比较简单,内容也不是很复杂,主要是练练手吧算是,顺便熟悉一下快排算法,不得不说快排是一个非常优秀的代码,思路非常清晰,实现起来也非常快,更好的是平均时间复杂度只有O(NlogN),可以说是个非常优秀的算法了.

上一篇下一篇

猜你喜欢

热点阅读