链表之调整顺序

本文探讨了如何在Java中对单链表的节点进行顺序调整。通过详细的源代码解析,阐述了链表操作的基本步骤和技巧,旨在帮助读者深入理解链表数据结构及其操作方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public class LinkModify {
 
  /**
   * 问题描述:2014 Microsoft 校招最后一题:
   *   给定一个单链表L (L0,L1,L2,...,Ln)要求将其变化为 L(L0,Ln,L1,Ln-1,L2,Ln-2,...),同时要求空间复杂度为O(1)并且只允许修改next域;
   * 思路:这道题本质上就是将一个链表的后半部分的每一个节点依次按倒序插入到链表的前半部分相邻两元素之间,因此可以将过程分解为如下几个步骤:
   * 1.确定需要移动的链表段的起始节点
   *   1.1 扫描链表,得到所有的节点数目length;O(N)
   *   1.2  用length/2得到链表的中间节点,则中间节点的下一个节点即为需要移动部分的起始节点;
   *   1.3            再次遍历链表,分别用指针指向这些关键节点;O(N/2)
   * 2. 逆序链表的后半部分。并将逆序后的部分拼接至原链表上。O(N/2);
   * 3. 从需要移动的起始节点开始遍历,将后半部分的节点一个个的插入前半部分的制定位置。O(N/2)
   * @author wangwei;
   * @since 2014/09/29
   */
  public static class Node{
     public int data;
     public Node next;
     public Node(int data){
        this.data=data;
        this.next=null;
      }
   }
  public  Node head;
  public LinkModify(int[] list){
     head=new Node(list[0]);
      Node now=head;
     for(int i=1;i<list.length;i++){
         Node one=new Node(list[i]);
         now.next=one;
         now=one;
      }
   }
  public void Modify(){
     //count the number of all nodes;
      Node now=head;
     int length=0;
     while(now!=null){
         length++;
         now=now.next;
      }
      now=head;
     //find the mid point;
     int mid=length/2;
      Node nd_end;
     int i=0;
     while(i<mid){
         now=now.next;
         i++;
      }
      nd_end=now;
     //reverse the part behind mid point
      Node parent=null;
      Node start=nd_end.next;
      Node after;
     while(start!=null){
         after=start.next;
         start.next=parent;
         parent=start;
         start=after;
      };
      nd_end.next=parent;
     //insert each node after mid point into front part;
      Node before=head;
      Node runner=nd_end.next;
     while(runner!=null){
         nd_end.next=runner.next;
         runner.next=before.next;
         before.next=runner;
         before=runner.next;
         runner=nd_end.next;
      }
   }
  public static void main(String[] args) {
     // TODO Auto-generated method stub
     int[] list={1,2,3,4,5,6,7,8,9,0};
      LinkModify lm=new LinkModify(list);
      lm.Modify();
      Node head=lm.head;
     while(head!=null){
         System.out.println(head.data);
         head=head.next;
      }
    
   }
 
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值