最近保研成功,没啥事情在看Java,所以处于新学习的状态,也没怎么写博客,不过正好有朋友问到关于链表的快排的问题,所以我也了解了一下,顺便在这里做个记录,同时开个头,以后也要多写点博客了,毕竟这一年都没啥事情.
-
简介
给定一个单链表的头节点,要将该链表排序. 这个问题的解法实际上有很多,这里我主要写一下快排的实现.值得注意的是,我们这里用的是值交换,并不是指针交换,对于单链表问题有时候使用值交换是非常方便的,避免了很多的指针操作. -
思路
办法实际上不难,我们回忆一下快排的思路,先选取一个key,然后以key为标准,将数组划分为两个子数组,一个子数组的所有值都小于key,另一个子数组的所有值都大于等于key,然后再对这两个子数组重复之前的操作,最终整个数组都排序完成.
但是我们这里应该怎么办呢,其实思路不算难,我们先选取第一个元素作为key,当然key的选取可能有思路,但这个不是快排的重点,我们接下来保存两个指针,假设一个指针为p,一个指针为q,我们希望p当前指向的值以及在p前面的值都是小于key的,而处于p以及q之间的值都是大于等于key的,因此当q到达链表的尾端时,数组就已经分组完成了,显然这和数组快排的思路是基本一致的. -
具体步骤
暂时我也不知道有什么工具可以用来画这个图,所以就手画了一哈,但是大概思路是没有问题的,希望大家理解一下.
image.png -
代码实现
由于我最近都在看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),可以说是个非常优秀的算法了.
网友评论