前言
在快速排序中,我们都是将数组划分为小于,等于,大于三个部分。那么在链表中怎么划分呢?
一、要求是什么?
要求用链表实现快速排序的一次过程。也就是一次Partition
二、情景区分
1.笔试
1.1 思路
笔试简单,不需要考虑空间复杂度,那太简单了。直接创立一个等同与链表的数组,直接对数组套用一次快速排序就行
1.2代码实现
//节点定义
public static class Node{
public int value;
public Node next;
public Node(int data) {
this.value=data;
}
}
//直接创立一个与链表大小相同的数组
public static Node listPartition1(Node head, int pivot) {
if(head == null) {
return head;
}
Node cur ;
cur = head;
int i = 0;
while(cur!=null) {
i++;
cur = cur.next;
}
Node[] nodeArr = new Node[i];
i = 0;
cur=head;
for(i=0;i!=nodeArr.length;i++) {
nodeArr[i] = cur;
cur = cur.next;
}
arrPartition(nodeArr,pivot);//进行一次partition
for (i = 1; i != nodeArr.length; i++) {
nodeArr[i - 1].next = nodeArr[i];
}
nodeArr[i-1].next = null;
return nodeArr[0];
}
//这个就是快速排序的partition一模一样
public static void arrPartition(Node[] nodeArr,int pivot) {
int small = -1;
int big = nodeArr.length;
int index = 0;
while(index !=big) {
if(nodeArr[index].value<pivot) {
swap(nodeArr,++small,index++);
}else if(nodeArr[index].value==pivot) {
index++;
}else {
swap(nodeArr,--big,index);
}
}
}
//交换两个数组
public static void swap(Node []nodeArr,int a,int b) {
Node tmp = nodeArr[a];
nodeArr[a] = nodeArr[b];
nodeArr[b] = tmp;
}
2.面试
2.1思路
由于是面试,必须淘汰大部分和你一同竞争的对手,所以我们必须考虑空间复杂度,所以为了减少空间的应用:- 我们就创立六个指针(java引用)分别代表小于,等于,大于的区间端点。
- 如何从头遍历数组,如果小于,就放入小于区间
- 等于放入大于区间
- 大于放入大于区间
- 注意判断一开始是否为空,才开始放,如果为空就放到头节点上
- 最后将三个区间链接到一起就行
- 但是要注意链接的时候是否为空,要是为空,这个区间就不连了
2.2代码实现
代码如下
public static Node listPartition2(Node head,int pivot) {
Node sH = null; // small head
Node sT = null; // small tail
Node eH = null; // equal head
Node eT = null; // equal tail
Node bH = null; // big head
Node bT = null; // big tail
Node next = null;
while(head!=null) {
next = head.next;
head.next = null;
if(head.value<pivot) {
if(sH==null) {
sH = head;
sT = head;
} else {
sT.next = head;
sT = head;
}
}else if(head.value == pivot) {
if(eH ==null) {
eH = head;
eT = head;
}else {
eT.next = head;
eT = head;
}
} else {
if(bH == null) {
bH = head;
bT = head;
} else {
bT.next = head;
bT = head;
}
}
head = next;
}
if(sT != null) {
sT.next = eH;
eT = eT ==null? sT:eT;
}
if(eT!=null) {
eT.next = bH;
}
return sH != null ?sH :eH !=null?eH:bH;
}
}
总结
注意区分面试与笔试的区别,面试需要考虑的东西更多,笔试需要考虑的东西少