将单向链表按某值划分成左边小,中间相等,右边大

来源:互联网 发布:大数据平台技术架构图 编辑:程序博客网 时间:2024/04/25 20:15

题目:给定一个单向链表的头结点head,节点的值类型是整型,再给定一个整数privot。实现一个调整链表的函数,将链表调整为左部分都是值小于privot的节点,中间部分都是值等于privot的节点,右部分都是大于privot的节点。
例如:链表9-0-4-5-1,pivot=3。
调整后是1-0-4-9-5,也可以是0-1-9-5-4。
解法1:我们可以利用数组额外空间来实现:
1。先遍历一遍链表,得到链表长度。
2。建立一个链表数组。
3。利用三向快排的划分
4。调整数组中的next值。
代码如下:

class Node{    public int value;    public Node next;    public Node(int data){        this.value=data;    }}public class quicklist {    public Node listPartition1(Node head,int privot){        if (head==null){            return head;        }        Node 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;        }        //调整在数组中的顺序        arrPartion(nodeArr,privot);        //调整赋值        for (i = 0; i != nodeArr.length; i++) {            nodeArr[i-1].next=nodeArr[i];//        }        nodeArr[i-1].next=null;        return nodeArr[0];    }    /**     * 三向切分快排一趟交换,需要三个记录量     * @param nodeArr     * @param privot     */    private void arrPartion(Node[] nodeArr, int privot) {        int small=-1;        int big=nodeArr.length;        int index=0;        while (index!=big){            if (nodeArr[index].value<privot){                swap(nodeArr,++small,index++);            }else if (nodeArr[index].value==privot){                index++;            }else {                swap(nodeArr,--big,index);            }        }    }    private void swap(Node[] nodeArr, int i, int j) {        Node tmp=nodeArr[i];        nodeArr[i]=nodeArr[j];        nodeArr[j]=tmp;    }}

解法二:不需要额外空间复杂度的情况下完成调整:
1。将原链表中的所有节点一次划分进三个链表,三个链表分别为small代表左部分,equal代表中间部分,big代表右部分。
例如,链表7-9-1-8-5-2-5,privot=5。在划分之后,small,equal,big分别为:
small:1-2-null
equal:5-5-null
big:7-9-8-null
2。重新串联
3。需要重点判断null。
具体代码这里不予列出。。

0 0
原创粉丝点击