简体   繁体   English

链表Java替换节点

[英]Linked Lists Java Replacing Nodes

I'm having difficulty with a linked lists program. 我在使用链表程序时遇到困难。 I want to write a method that destructively replaces the value in each node n by the sum of the values in the tail of the list. 我想写一个方法,用列表尾部的值之和破坏性地替换每个节点n中的值。 So if the list is 2,3,5,7; 因此,如果列表为2,3,5,7; I want to change it to 17,15,12,7. 我想将其更改为17,15,12,7。 I am given a program where I have to add a method that does this. 给我一个程序,在其中我必须添加执行此操作的方法。 I can change the first number, but I can not change the other three, and I am stuck. 我可以更改第一个数字,但不能更改其他三个数字,因此我被卡住了。 If anyone could help me, that would be great. 如果有人可以帮助我,那就太好了。

Original Program 原始程序

public class IntList {
private int value;     
private IntList next;


public IntList(int v, IntList n) {          // Constructor
    value = v;
    next = n;
  }

public int getValue() { return value; }       // Getters
public IntList getNext() { return next; }
public void setValue(int v) { value = v; }    // Setters
public void setNext(IntList n) { next = n; }

// Find the last node of a linked list.
public IntList findLast() {
   if (getNext() == null) return this;
   else return getNext().findLast();
 }

// Add a new node with value v at the end of l;

public void addEnd(int v) {
    findLast().setNext(new IntList(v,null));
  }

// Add up the values in a list, recurring down the owner
public int sumList() {
   if (getNext() == null) return getValue();
   else return getValue() + getNext().sumList();
  }


// Convert list of int to string

// Recursive method for constructing the end of the string, after the
// initial open bracket.

 public String toString1() {
   if (getNext() == null)
      return getValue() + "]";
   else return getValue() + ", " + getNext().toString1();
 }

// Top level rountine that starts with the "[" and then calls toString1 to
// do the rest.

  public String toString() {
    return "[" + toString1();
  }

// Recursive method for finding the sum of a list, using recursion down
// an argument. Note that this is a static method, associated with the class
// not with an object owner.

 static public int sumListArg(IntList l) {
    if (l==null) return 0;
    else return l.getValue() + sumListArg(l.getNext());
   }

 static public void main(String[] args) {
   IntList l = new IntList(2,null);
   l.addEnd(3);
   l.addEnd(5);
   l.addEnd(7);
   System.out.println("h");
   System.out.println(l.toString());
   System.out.println("Sum = " + l.sumList());
} // end main
} // end RecursiveIntList    

Here is what I have so far for my method (I think it's logically ok, but it's incorrect): 这是到目前为止我的方法(我认为这在逻辑上还可以,但是不正确):

 public static void runningSum(IntList l)
{ 
     l.setValue(l.sumList());

    while(l.getNext() != null) 
     {
        l.setNext(l.getNext()); //Set Next to be the next reference
        l.getValue();  //Get the Next's value
        l.setValue(l.sumList()); //Add the rest of the numbers together
     }

     if(l.getNext() == null)
     {
         l.setValue(l.getValue());
     }

     System.out.println(l.toString());
}

There is a nice and elegant solution: 有一个不错的解决方案:

public int sumList() {
    if (getNext() == null) {
        return getValue();
    }
    value = getValue() + getNext().sumList();
    return value;
 }

In this method you recursively iterate through the List, and summarize all the elements that are behind the current element, and set the value at the same time. 在此方法中,您递归地遍历列表,总结当前元素后面的所有元素,并同时设置值

This is the code: 这是代码:

public static void runningSum(IntList l)
{ 
    IntList head = l;
    int rSum = l.sumList();

    while(l != null) 
    {
        int curRS = rSum;
        curRS -= l.getValue();
        l.setValue(rSum);
        rSum = curRS;
        l = l.getNext();
    }

    System.out.println(head.toString());
}

I'll break it in several parts to explain what's going on. 我将其分为几个部分以解释发生了什么。 We want to code a procedure that takes the head of a list and alters the list in the way you describe; 我们要编写一个过程,该过程采用列表的开头并按照您描述的方式更改列表。 basically the first element must become the sum of all the original elements; 基本上,第一个元素必须成为所有原始元素的总和; the second element must be the sum of all elements except the first, and so on. 第二个元素必须是第一个元素之外的所有元素的总和,依此类推。 The last element, the tail, must remain unchanged. 最后一个元素,即尾部,必须保持不变。

public static void runningSum(IntList l)
{

The function we need to remember the head that was passed to the function; 这个函数我们需要记住传递给该函数的头部; we save l in a variable called head . 我们将l保存在名为head的变量中。

    IntList head = l;

The running sum for the first element is the sum of all elements; 第一个元素的总和是所有元素的总和; so we call sumList and store the result in a variable called rSum . 因此我们调用sumList并将结果存储在名为rSum的变量中。

    int rSum = l.sumList();

This is a very typical idiom in data structures programming; 这是数据结构编程中非常典型的习惯用法。 while the element is not null, you loop. 当元素不为null时,您循环。

    while(l != null) 
    {

The running sum of the next element is rSum minus the value of the current element. 下一个元素的运行总和是rSum减去当前元素的值。

        int nextRS = rSum - l.getValue();

Now we can set running sum of the current element to rSum . 现在我们可以将当前元素的运行总和设置为rSum

        l.setValue(rSum);

For the next iteration, the current running sum is nextRS . 对于下一次迭代,当前运行总和是nextRS Finally we update l to point to the next element. 最后,我们更新l指向下一个元素。

        rSum = nextRS;
        l = l.getNext();
    }

If we didn't keep track of head , now we wouldn't know what to print. 如果我们没有记录的,现在我们不知道打印什么。

    System.out.println(head.toString());
}

Linked lists lend themselves to recursion. 链接列表适合于递归。 A recursive solution might look like this: 递归解决方案可能看起来像这样:

public static void runningSum(IntList l) {
    if (l.getNext() != null) {
        runningSum(l.getNext());
        l.setValue(l.getValue() + l.getNext().getValue());
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM