不开辟新存储空间的情况下完成链表的逆置

结点的数据结构为

public class Node {
    int data=0;
    Node next=null;

    public Node(int data){
        this.data=data;
    }
    public Node(){}
}

单链表的数据结构为

public class ListNode {
    private Node head = new Node();
}

链表为空的情况下只有一个单独的头结点

逆置过程:
由于不能开辟新的存储空间,所以只能给几个需要操作的结点改个新名字来使用

逆置思路:由于需要逆转顺序,所以不能从头结点直接取出后一个结点塞到链表末尾,而是每次将链表中初始末尾结点的前一个结点取出,并插入到链表末尾.

故而逆置过程为:声明一个尾结点“end”用来标记链表的“真”末尾位置(即不管链表如何改变,end始终为最末尾的结点),其次需要声明一个常结点"change"用来标记链表初始状态下的末尾结点.最后需要一个指针结点node,用于辅助查找确定需要被修改的位置.

声明完毕后,遍历链表,将链表的末尾地址分别赋值给尾结点"end"与常结点"change",由于遍历完成后指针结点的位置到了末尾,需要手动将其放到头结点位置.

开始进行逆置:
判断逆置是否结束的条件为:头结点的下一个结点即为常结点.
指针结点将作为一个"小链表"的头结点使用(当前"node"结点的下下个结点为常结点"change",此三个结点构成的小型链表),小链表中共三个结点,若小链表的末尾结点为常结点,则小链表中的第二个结点需要被修改.

具体操作为:在node.next.next==change的情况下

end.next=node.next(将end的next指针指向node结点的下一个结点)

end=end.next(end结点向后移动一位,确保用于处于链表的末尾)

node.next=change(将node结点的next指针指向常结点"change",抹掉原中间结点的位置,使其真正成为尾结点)

node=head(修改结束后将node重新放到头结点位置)

end.next=null;(让现end结点的指针指向空,防止出现循环嵌套)

public void turn(ListNode listNode){
        Node node = listNode.head.next;
        Node end = null;        //定义尾结点
        Node change = null;     //定义常结点即链表初始状态的末尾结点
        while(node!=null){
            end = node;
            node=node.next;
        }       //遍历整个链表,并定义出尾结点
        change = end;       //将尾结点地址给常结点
        node=head;      //指针结点重新回到头结点位置
        while (head.next!=change){
            if (node.next.next==change){
                end.next=node.next;
                end=end.next;
                node.next=change;
                node=head;
                end.next=null;
            }else {
                node=node.next;
            }
        }       //执行逆置操作
    }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值