链表----将单链表按某值划分成左边小、中间相等、右边大的形式

 

关键点:

1、利用快排的思想

  • 将链表放在数组中;
  • 利用荷兰国旗思想将链表进行调整;
  • 然后将数组中的链表串联起来 。

2、仅用链表结构

代码:

  • 将链表分成三个部分small、equal、big
  • 将三个链表串联起来
  • 特别注意三个链表都有可能为空
//一、荷兰国旗改进快排 + LinkedList /Node[] /ArrayList实现
	//T = O(N)  S = O(N)
	public static Node partition1(Node head,int pivot) {
		if(head == null) return head;
		//1、将链表存放在数组里
		LinkedList<Node> arr = new LinkedList<Node>();
		Node cur = head;	
		while(cur != null) {
			arr.add(new Node(cur.value));
			cur = cur.next;
		}
		
		//2、将数组进行partition调整
		int less = -1;
		int more = arr.size();
	    int i = 0;
		while(i != more) {
			if(arr.get(i).value < pivot) {
				swap(arr,++less,i++);
			}else if(arr.get(i).value == pivot) {
				i++;
			}else {
				swap(arr,--more,i);
			}
		}
		
		//3、将调整后的数组串成链表
		for(i = 1;i < arr.size();i++) {
			arr.get(i-1).next = arr.get(i);
		}
		arr.get(arr.size()-1).next = null;
		
		return arr.get(0);
	}
	
	public static void swap(LinkedList<Node> arr,int i,int j) {
		Node temp = arr.get(i);
		arr.set(i, arr.get(j));
		arr.set(j, temp);
	}
	//二、借用链表结构+指针实现
	//T = O(N)  S = O(1)
	public static Node partition2(Node head,int pivot) {
		if(head == null) return null;
		//1、将链表分成三部分small 、 equal、big
		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 cur = head;
		Node next = null;//记录下一个节点 因为每操作一个节点会将该节点与链表断开
		while(cur != null) {
			next = cur.next;
			cur.next = null;//断开该节点 将该节点连接到相应的部分中
			if(cur.value < pivot) {
				if(sH == null) {
					sH = cur;
					sT = cur;
				}else {
					sT.next = cur;
					sT = cur;
				}
			}else if(cur.value == pivot){
				if(eH == null) {
					eH = cur;
					eT = cur;
				}else {
					eT.next = cur;
					eT = cur;
				}
			}else {
				if(bH == null) {
					bH = cur;
					bT = cur;
				}else {
					bT.next = cur;
					bT = cur;
				}
			}
			cur = next;
		}
		//2、将链表三部分连接起来
		//注意:每一部分都有可能没有节点
		//2.1 链接small和equal部分
		if(sT != null) {
			sT.next = eH;
			eT = eT==null ? sT : eT;
		}
		//2.2前面和big部分链接
		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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值