反转单链表(java实现)

题目描述:

输入一个链表,反转链表后,输出链表的所有元素。
(hint : 请务必使用链表)

输入:

输入可能包含多个测试样例,输入以EOF结束。
对于每个测试案例,输入的第一行为一个整数n(0<=n<=1000):代表将要输入的链表的个数。
输入的第二行包含n个整数t(0<=t<=1000000):代表链表元素。

输出:

对应每个测试案例,
以此输出链表反转后的元素,如没有元素则输出NULL。

样例输入:

5
1 2 3 4 5
0

样例输出:

5 4 3 2 1
NULL

方法一:在下图中,结点 h , i , j 是相邻的三个结点,假设i之前的所有结点已经完成逆转,直接将i的下一个结点指向 h,很明显会发现链表断裂。因此必须将 i 的后一个结点保存,不然将遍历不到结点。因此需要三个指针,分别指向i的前一个结点,i 结点,以及 j 结点。

//遍历,将当前节点的下一个节点缓存后更改当前节点指针;
    public static Node reverse(Node header){
        if(header == null || header.getNextNode()==null)
            return header;
        //转化后的头结点
        Node pReversedHeader = null;
        //当前节点
        Node pNode = header;
        //当前节点前面的一个节点
        Node pPrev = null;
        while(pNode != null){
            //将当前节点的下一个节点缓存,防止断开链
            Node pNext = pNode.getNextNode();
            //下一个节点为空,证明已经遍历到尾部节点,头结点指向它
            if(pNext == null)
                pReversedHeader = pNode;
            //当前节点指向上一个节点
            pNode.setNextNode(pPrev);
            //更改当前节点,以及其上一个节点
            pPrev = pNode;
            pNode = pNext;  
        }
        return pReversedHeader;
    }

方法二:以头插法实现链表的反转,head指针始终指向第一个节点,从第一个结点开始一直将后续结点插入head之后。

//类似与头插法
    public static Node reverse2(Node header){
        if(header == null || header.getNextNode() == null)
            return header;
        Node p1=header;  
        Node p2=header.getNextNode();  
        while(p2!=null){  
            p1.setNextNode(p2.getNextNode());//记录下p的下一个节点  
            p2.setNextNode(header);  //指向第一个节点
            header=p2;  //头结点始终指向第一个结点
            p2=p1.getNextNode();//准备将p的下一个节点放到表头  
       }  
       return header;  
    }

实现代码:

package com.other.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;

class Node {     
    private int value; 
    private Node nextNode;     
    public int getValue() {
        return value;
    }
    public void setValue(int value) {
        this.value = value;
    }
    public Node getNextNode() {
        return nextNode;
    }
    public void setNextNode(Node nextNode) {
        this.nextNode = nextNode;
    }
    public Node(int value,Node nextNode) {     
        this.value = value;  
        this.nextNode = null;
    }          
}   
public class ReverseList {

    /**
     * 反转链表
     * 1、遍历,将当前节点的下一个节点缓存后更改当前节点指针;
     * 2、类似与头插法
     */
    //方法二:类似与头插法
    public static Node reverse2(Node header){
        if(header == null || header.getNextNode() == null)
            return header;
        Node p1=header;  
        Node p2=header.getNextNode();  
        while(p2!=null){  
            p1.setNextNode(p2.getNextNode());//记录下p的下一个节点  
            p2.setNextNode(header);  //指向第一个节点
            header=p2;  
            p2=p1.getNextNode();//准备将p的下一个节点放到表头  
       }  
       return header;  
    }
    //方法一:遍历,将当前节点的下一个节点缓存后更改当前节点指针;
    public static Node reverse(Node header){
        if(header == null || header.getNextNode()==null)
            return header;
        //转化后的头结点
        Node pReversedHeader = null;
        //当前节点
        Node pNode = header;
        //当前节点前面的一个节点
        Node pPrev = null;
        while(pNode != null){
            //将当前节点的下一个节点缓存,防止断开链
            Node pNext = pNode.getNextNode();
            //下一个节点为空,证明已经遍历到尾部节点,头结点指向它
            if(pNext == null)
                pReversedHeader = pNode;
            //当前节点指向上一个节点
            pNode.setNextNode(pPrev);
            //更改当前节点,以及其上一个节点
            pPrev = pNode;
            pNode = pNext;  
        }
        return pReversedHeader;
    }
    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        StreamTokenizer cin = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        while(cin.nextToken()!=cin.TT_EOF){
            int n = (int)cin.nval;
            if(n==0){
                System.out.println("NULL");
                continue;
            }
            cin.nextToken();
            Node header = new Node((int)cin.nval,null),current=header;
            /*
             * current用来操作当前节点的下一个节点;
             * header不变,依然是指向第一个节点
             * */
            for(int i=0;i<n-1;i++){
                cin.nextToken();
                current.setNextNode(new Node((int)cin.nval,null));
                current = current.getNextNode();
            }
            //Node reversedHeader = reverse(header);
            Node reversedHeader = reverse2(header);
            StringBuilder str = new StringBuilder();
            while(reversedHeader!=null){
                str.append(reversedHeader.getValue()+" ");
                reversedHeader = reversedHeader.getNextNode();
            }
            System.out.println(str.substring(0, str.length()-1));
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值