Sort List 【leetCode】

目录:
1、题目及分析
    1.1 题目
    1.2 分析

1、题目及分析
1.1 题目:
     Sort a linked list in  O ( n  log  n ) time using constant space complexity.
1.2 分析
     O ( n  log  n )的复杂度,所以不能采用冒泡等,这里采用合并排序算法,且为了不采用递归的方式,所以得到如下代码。

2、实现

 // Definition for singly-linked list.
  class ListNode {
      int val;
      ListNode next;
      ListNode(int x) {
          val = x;
          next = null;
      }
  }

public class SortList {

    public int length(ListNode head){ //求链表的长度
        int count = 0;
        ListNode h = head;
        while(null != h){
            count ++;           
            h = h.next;
        }
        return count;
    }
    public ListNode sortList(ListNode head) {//返回排序的结果
        int len = length(head); 
        //System.out.println(len);
        int window = 2;//
        ListNode pointL = null;
        ListNode pointR = null;
        ListNode tmp = null;
        ListNode tmp2 = null;
        ListNode headPointer = new ListNode(0); //定义一个头指针
        ListNode headPointerTmp = head;         //定义一个暂头指针
        headPointer.next = head;    //将头指针指向传入的链表
        headPointerTmp = headPointer;      //暂存头指针指向头指针
        if(0 == len || 1== len) return head; //如果长度为1,则直接返回

        while(window/2 < len){  //二分法每个区间用2^n大小表示,如果len=5,那么必须运算到window=8才能结束
                                //这里采用 len大于window/2 当len=5时,8/2=4仍然运行,16/2=8才结束
            for(int i=len ; i>0; i-=window){
                pointL = headPointerTmp;
                pointR = headPointerTmp;

                for(int k=window/2; k>0; k--){
                    if(null == pointR.next) break;
                    pointR =  pointR.next;//移动指针
                }

                for(int j=window/2; j>0; )  {//由于使用分治,所有待排序的,都已经按照一定顺序排列
                                             //R的操作最多window/2次
                    if(pointR == pointL || null == pointR.next) break; //L中所有都遍历了就结束
                    if(pointR.next.val < pointL.next.val){//满足条件则进行插入操作
                        /* pre->A->B->C>D  要将C插入到A之前
                         * pointL = pre; pointR = C;
                         * pre->C;C->A;B->D
                         */
                        tmp = pointL.next;          //保存A        
                        tmp2 = pointR.next.next;    //保存D
                        pointL.next = pointR.next;  //pre->C 
                        pointL.next.next = tmp;     //C->A
                        pointR.next = tmp2;         //B->D
                        pointL = pointL.next;       //后移一位
                        //print(headPointer.next);
                        j--;    //每次进行插入后,进行j--
                    }
                    else{
                        pointL = pointL.next; 
                    }
                }
                for(int k=window; k>0; k--){    //将指针移动到下一个windonw内
                     if(null == headPointerTmp.next) break; //这里可以处理非2^n长度的链表
                    headPointerTmp = headPointerTmp.next;   
                }

            }
            
            window = window * 2; //扩大窗口
            headPointerTmp = headPointer;//重新指向最开始
        }
        return headPointer.next; //返回头结点
    }
    public void print(ListNode head){
        ListNode point = head;
        for(int m=length(head); m>0; m--){
            System.out.print(point.val + " ");
            point = point.next;
        }
        System.out.println();
    }
    public static void main(String[] args) {
        ListNode l1 = new ListNode(4);
        ListNode l2 = new ListNode(2);
        ListNode l3 = new ListNode(1);
        ListNode l4 = new ListNode(3);
        ListNode l5 = new ListNode(5);
        ListNode l6 = new ListNode(-1);
        ListNode l7 = new ListNode(-2);
        ListNode l8 = new ListNode(-100);
        ListNode l9 = new ListNode(-1000);
        ListNode l10 = new ListNode(-1000);
        ListNode k = null;
        
        ListNode lm = null;
        SortList s = new SortList();

        //k.next = l1;
        l1.next = l2;
        l2.next = l3;
        l3.next = l4;
        l4.next = l5;
        l5.next = l6;
        l6.next = l7;
        l7.next = l8;
        l8.next = l9;
        l9.next = l10;


        lm = s.sortList(l1);
        s.print(lm);
        //System.out.println(lm.val);
        //System.out.println(lm.next.val);

    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值