Java数据结构与算法之-------如何多链表进行重新排序

1.问题

   给定链表 L0--L1--L2 ----L3 ---...... Ln,把链表重新排序为L0--Ln----L1---Ln-1----L2---Ln-2  。

要求: 1) 在原来链表的基础上排序,不能申请新的节点。

            2)只能修改节点的next域,不能修改数据域。

2 思路分析:

    1)首先找到链表的中间节点、

    2)对链表的后半部分进行逆序

  3)合并:分别从链表中各自取出一个节点,进行合并、

3 代码实现

package linkedlist.chongxinpailie;

public class TwoRealign {

    public static void main(String[] args) {
        int i=1;
        LNode head=new LNode();
        head.next=null;
        LNode temp=null;
        LNode cur=head;
        //构造链表
        for (;i<8;i++){
            temp=new LNode();
            temp.date=i;
            temp.next=null;
            cur.next=temp;
            cur=temp;
        }
        System.out.print("排序前:");
        for (cur=head.next;cur!=null;cur=cur.next){
            System.out.print
                    (cur.date+" ");
        }
        Reorder(head);
        System.out.println("排序后:");
        for (cur=head.next;cur!=null;cur=cur.next){
            System.out.print
                    (cur.date+" ");
        }
    }
    /**
     *   把链表从中间变成两个子链表
     * @param head  头结点
     * @return   返回链表的中间节点
     */
    private static LNode FindMiddleNode(LNode head){
        if (head==null||head.next==null){
            return head;
        }
        LNode fast=head;//遍历链表时,每次前进两步
        LNode slow=head;//遍历链表时,每次前进一步
        LNode slowpre=head;
        //这样的话,就是当fast遍历到链表尾部时,slow正好遍历到链表中间
        while (fast!=null && fast.next!=null){//因为fast一次走两步,所以要fast!=null && fast.next!=null
            slowpre=slow;//记录slow的位置
            slow=slow.next;//后移一步
            fast=fast.next.next;//后移两步
        }
        //把两个链表断开成两个独立的子链表
        slowpre.next=null;
        return slow;
    }

    /**
     *  对不带头结点的链表进行反转
     * @param head  链表头结点
     * @return
     */
    public static LNode Reverse(LNode head){
        if (head==null||head.next==null){
            return head;
        }
        LNode pre=head;//前驱结点
        LNode cur=head.next;//当前节点
        LNode next=null;//后继节点
        pre.next=null;
        //使遍历到的节点指向起前驱节点
        while (cur!=null){
            next=cur.next;//将当前节点的后一个节点暂存
            cur.next=pre;//让当前的节点指向前驱节点
            pre=cur;//pre后移
            cur=cur.next;
            cur=next;//当前节点后移
        }
        return pre;
    }

    /**
     *  对链表进行拼接
     * @param head  头结点
     */
    public static void Reorder(LNode head){
        if (head==null || head.next==null|| head.next.next==null){
            return;
        }
        //前半部分链表的第一个节点
        LNode cur1=head.next;
        LNode mid = FindMiddleNode(head);
        //后半段链表的第一个几点
        LNode cur2 = Reverse(mid);
       //辅助变量
        LNode temp=null;
        //合并两个链表
        while (cur1.next!=null){
            temp=cur1.next;//将cur1的后继节点保存起来
            cur1.next=cur2;//令cur1 指向cur2
            cur1=temp;//cur1后移

            temp=cur2.next;
            cur2.next=cur1;
            cur2=temp;
        }
        cur1.next=cur2;
    }


}
class LNode{
    LNode next;
    int date;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值