用Java反转链表的程序

时间:2014-11-05 16:06:04

标签: java linked-list

我编写了以下代码,其中rev(list,list)方法不起作用。请帮我确定是什么问题。

import java.io.*;
public class list
{
    int d;
    list l;
    list()
    {
        d=0;
        l=null;
    }

    void create()throws IOException
    {
        int n;// store number of nodes
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        System.out.println("Enter the first data");
        this.d=Integer.parseInt(br.readLine());
        System.out.println("Enter number of nodes to be made");
        n=Integer.parseInt(br.readLine());
        list temp;
        list ptr=this;
        for(int i=1;i<n;i++)
        {
            temp=new list();
            System.out.println("Enter the next data");
            temp.d=Integer.parseInt(br.readLine());
            temp.l=null;
            ptr.l=temp;
            temp=null;
            ptr=ptr.l;
        }
    }

    void delete(list lst, int n)
    {
        list ptr=lst;
        list ptr1=ptr;
        int c=1;
        while(c<n)
        {
            ptr1=ptr;
            ptr=ptr.l;
            c++;
        }
        ptr1.l=ptr.l;
        ptr.l=null;
        ptr=null;
        ptr1=null;
    }

    void insertmid(list lst,int x, int n)
    {
        list temp=new list();
        temp.d=x;
        temp.l=null;
        list ptr=lst;
        int c=1;
        while(c<n)
        {
            ptr=ptr.l;
            c++;
        }
        temp.l=ptr.l;
        ptr.l=temp;
    }

    void rev(list lst,list lst1)
    {

        lst1=null;
        list ptr=new list();

        while(lst!=null)
        {
            ptr =lst;
            lst=lst.l;
            ptr.l=lst1;
            lst1=ptr;

        }
    }


    void display()
    {
        list ptr=this;

        while(ptr!=null)
        {
            System.out.print(ptr.d+"\t");
            ptr=ptr.l;
        }
        System.out.println();
    }

    public static void main(String args[])throws IOException
    {
        list l2=new list();
        list l3=new list();

        l2.create();
        l2.display();
        l2.insertmid(l2,14,2);
        l2.display();
        l2.delete(l2, 3);
        l2.display();
        l2.rev(l2,l3);
        l2.display();

    }
}

5 个答案:

答案 0 :(得分:1)

您应该做的第一件事是让自己熟悉Java Naming Conventions,因为它会使您的代码更清晰,更易理解。您当前的代码不区分类或方法或变量。

其次,您似乎来自C ++背景,并且不知道Java总是passes by value

这是你做的一件事没有意义:

void rev(list lst,list lst1)
{

    lst1=null;  // this is pointless, essentially, you are using a passed argument as a local variable. 
    // ...

以下代码几乎相同:

void rev(list lst)
{

    list lst1=null; //just create lst1 right here, don't need to pass it in as a parameter
    // ...

现在,我不打算清理整个代码,但我会给你算法来反转你可以加入你的程序的链接列表:

public Node reverseList(Node head) {
    Node newHead = null;        // New head of the reversed list
    Node prev, curr, next;      // Tracker pointers to previous, current and next node
    prev = null;
    curr = head;
    next = null;
    while(curr != null) {       // Iterate through the list
        next = curr.next;       // Remember the next node
        curr.next = prev;       // Point the current node to the previous
        prev = curr;            // Update the previous node tracker to the current node
        curr = next;            // Update the current node tracker to the next node
        if(next == null) {      // If we reached list end, store the new head
            newHead = prev;
        }
    }
    return newHead;
}

答案 1 :(得分:0)

您可以使用Java Collection类尝试此操作:

import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

class ReverseList {
List<Integer>list=new LinkedList<Integer>();

public void initializeList(){
    Scanner in=new Scanner(System.in);
    System.out.println("Enter number of nodes:");
    int no=Integer.parseInt(in.next());

    for(int i=0;i<no;i++){
        list.add(Integer.parseInt(in.next()));
    }
    in.close();
}

public void displayList(){
    System.out.println(list);
}

public void reverseList(){
    List<Integer>list2=new LinkedList<Integer>();

    for(int i=list.size()-1;i>=0;i--){
        list2.add(list.get(i));
    }
    this.list=list2;

}

public static void main(String[] args) {
    ReverseList rl1=new ReverseList();
    rl1.initializeList();
    rl1.displayList();
    rl1.reverseList();
    rl1.displayList();
}
}

答案 2 :(得分:0)

遵循标准命名约定。这样做会使您的代码更多更容易阅读。特别是,引用类型(类和接口)的名称应以大写字母开头(例如List),而方法和实例变量的名称应以小写字母开头。

以下是对您的非工作方法的一些评论:

void rev(list lst,list lst1)
{

如果您立即放弃传递的任何值,则传递lst1是没有意义的,就像您在此处一样:

    lst1=null;

在这里初始化变量'ptr'也没有意义,因为你用它做的第一件事(在循环开始时)是分配一个新值。事实上,在循环体内声明它会更清晰。

    list ptr=new list();

以下循环看起来可能没问题,但考虑它离开最初由lst引用的对象的状态。提示:lst1已初始化为null

    while(lst!=null)
    {
        ptr =lst;
        lst=lst.l;
        ptr.l=lst1;
        lst1=ptr;
    }

现在考虑Java只有pass-by-value,所以传递给this方法的任何引用都不会从调用者的角度改变。

}

如果你还没有看到它,那么请考虑这个问题:哪个节点现在位于列表的首位?

在更一般的意义上,您有一些建模问题,因为您的list类尝试执行双重任务,不仅代表整体列表,还代表该列表中的节点。这可以工作,并且它具有可能有用的属性,但它也具有可能导致麻烦的属性。例如,您不能使用类的实例表示空列表。您也无法通过具有rev()签名的方法来有效地撤销您的班级实例所代表的列表。

答案 3 :(得分:0)

使用 Java类命名约定我准备并重写了您的代码,以便按照您的要求工作:

import java.io.*;
public class List
{
    private Integer data;
    private List next;

    List(Integer data, List next){
        this.data = data;
        this.next = next;
    }

    List(){
        this(0);
    }

    List(Integer data) {
        this(data, null);
    }

    List(List list) {
        this(list.getData(), list.getNext());
    }

    public void setData(Integer data) {
        this.data = data;
    }

    public Integer getData() {
        return this.data;
    }

    public void setNext(List next) {
        this.next = next;
    }

    public List getNext() {
        return this.next;
    }

    private List getElementAt(Integer element) {
        List tmp = this;
        for(int i = 0; i < element; i++){
            if (tmp.getNext() == null) {  // preventing NPE
                return tmp;
            }
            tmp = tmp.getNext();
        }
        return tmp;
    }

    public void add_nodes()throws IOException {
        Integer number_of_nodes;// store number of nodes
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("Enter number of nodes to add");
        number_of_nodes = Integer.parseInt(br.readLine());
        List ptr = this;
        for(int i = 1 ; i < number_of_nodes ; i++)
        {
            List temp = new List();
            System.out.println("Enter the next data");
            temp.setData(Integer.parseInt(br.readLine()));
            ptr.setNext(temp);
            ptr = ptr.getNext();
        }
    }

    /**
    * Function used to cut n-th element from list
    *
    * @param element - 0 means first element
    */
    public void delete(Integer element){
        List tmp = this.getElementAt(element);
        if (tmp.getNext() == null) {
            return;                // preventing NPE
        }
        tmp.setNext( tmp.getNext().getNext() ); //cutting
    }

    public void insertmid(Integer position, Integer data){
        List tmp = this.getElementAt(position);
        List element = new List(data, tmp.getNext());
        tmp.setNext(element);

    }

    public void rewind(){
        List tmp = this;
        List result = new List(this);
        result.setNext(null);
        while(tmp.getNext() != null) { 
            tmp = tmp.getNext();
            List current = new List(tmp);
            current.setNext(result);
            result = current;
        }
        this.setData(result.getData());
        this.setNext(result.getNext());
    }


    void display()
    {
        List tmp = this;
        while(tmp != null) {
            System.out.print( tmp.getData() + "\t");
            tmp = tmp.getNext();
        }
        System.out.println();
    }

    public static void main(String args[])throws IOException
    {
        List list = new List();

        list.add_nodes();
        list.display();
        list.insertmid(4, 2);
        list.display();
        list.delete(3);
        list.display();
        list.rewind();
        list.display();

    }
}

答案 4 :(得分:0)

我编写的代码仅用于在结尾处插入列表中的节点。 您可以添加新方法(函数)以在开头添加节点并根据您的要求从列表中删除节点。

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

class Node{
private int data;
private Node next;
private Node prev;

Node(Node n){
    this.data=n.data;
    this.next=n.next;
    this.prev=n.prev;
}

Node(int data){
    this.data=data;
    this.next=null;
    this.prev=null;
}
public int getData() {return data;}
public void setData(int data) {this.data = data;}

public Node getNext() {return next;}
public void setNext(Node next) {this.next = next;}

public Node getPrev() {return prev;}
public void setPrev(Node prev) {this.prev = prev;}
}   

class MyLinkedList{
    private Node start;
    private Node end;


    public Node getStart() {
        return start;
    }


    public void setStart(Node start) {
        this.start = start;
    }


    public Node getEnd() {
        return end;
    }


    public void setEnd(Node end) {
        this.end = end;
    }


    public boolean isEmpty(){
        return start==null;
    }

    //data from arguments
    public void addNode(int data) throws NumberFormatException, IOException{

        Node n=new Node(data);
        if(isEmpty()){
            start=end=n;
        }else
            if(start==end){
                start.setNext(n);
                n.setPrev(start);
                end=n;
            }
        else{
            end.setNext(n);
            n.setPrev(end);
            end=n;
        }

    }



    public void reverse() throws NumberFormatException, IOException{
        MyLinkedList revList=new MyLinkedList();
        Node currNode=this.getEnd();

        do{

            revList.addNode(currNode.getData());
            currNode=currNode.getPrev();
        }while(currNode!=null);

        this.start=revList.getStart();
        this.end=revList.getEnd();
    }

    public void traverseFromStart(){
        Node n=start;
        do{

            System.out.print(n.getData()+"-->");
            n=n.getNext();
        }while(n!=null);
        System.out.println();
    }

    public void traverseFromEnd(){
        Node n=end;
        do{

            System.out.print(n.getData()+"-->");
            n=n.getPrev();
        }while(n!=null);
        System.out.println();
    }

    public static void main(String[] args) throws NumberFormatException, IOException {
        MyLinkedList list=new MyLinkedList();
        System.out.print("Enter No. of Nodes:");
        BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
        int noOfNodes=Integer.parseInt(in.readLine());

        for(int i=0;i<noOfNodes;i++){
            System.out.print("Enter value of this node:");

            list.addNode(Integer.parseInt(in.readLine()));
        }


        list.traverseFromStart();
        list.traverseFromEnd();
        list.reverse();
        list.traverseFromStart();
        list.traverseFromEnd();

    }
}