将链表中的划分小于,等于,大于一个值(java实现链表Partition)


前言

在快速排序中,我们都是将数组划分为小于,等于,大于三个部分。那么在链表中怎么划分呢?


一、要求是什么?

要求用链表实现快速排序的一次过程。也就是一次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;
    }

}



总结

注意区分面试与笔试的区别,面试需要考虑的东西更多,笔试需要考虑的东西少

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

醉卧考场君莫笑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值