2014-09-25 30 views
0

現在,我的鏈接列表程序需要一個柺杖纔能有效地工作。我需要使用(0,0,null)節點關閉鏈表,因爲我的addToFront()方法的空頭條件不起作用。任何人都可以幫我解決這個問題嗎?我需要消除程序的零點,以便以後更容易處理,而這個小問題已經導致我幾個小時的痛苦。我知道這是一個失去參考的問題,請幫助我!我的鏈接列表添加方法失敗

輸出對於add()方法是正確的,因爲我已經實現了一個柺杖方法來殺死多項式的零點,但我真的想知道我在做什麼我的addToFront()方法有問題。這是最底部的方法,我知道if(head == null)部分失敗是因爲如果我沒有初始化列表的第一個節點並因此繞過它,我返回一個空列表。非常感謝你的幫助!

public Polynomial add(Polynomial p) 
{ 
    Polynomial newPoly = new Polynomial(); 
    newPoly.poly = new Node(0,0,null); 
    Node curr = this.poly; 
    Node curr2 = p.poly; 
    float co; 
    int deg; 

    while(curr!=null && curr2!=null) 
    { 
     if(curr.term.degree == curr2.term.degree) 
     { 
      co = curr.term.coeff + curr2.term.coeff; 
      deg = curr.term.degree; 
      curr=curr.next; 
      curr2=curr2.next; 
     } 
     else if(curr.term.degree > curr2.term.degree) 
     { 
      co=curr.term.coeff; 
      deg = curr.term.degree; 
      curr=curr.next; 
     } 
     else 
     { 
      co=curr2.term.coeff; 
      deg=curr2.term.degree; 
      curr2=curr2.next; 
     } 
     if(co!=0) 
     { 
      addToFront(co,deg,newPoly.poly); 
     } 
     // addToBack(co,deg,newPoly.poly); 
     // System.out.println(newPoly.poly.term.coeff); 
    } 
    while(curr!=null) 
    { 
     co=curr.term.coeff; 
     deg=curr.term.degree; 
     curr=curr.next; 
     if(co!=0) 
     { 
      addToFront(co,deg,newPoly.poly); 
     } 
    } 
    while(curr2!=null) 
    { 
     co=curr2.term.coeff; 
     deg=curr2.term.degree; 
     curr2=curr2.next; 
     if(co!=0) 
     { 
      addToFront(co,deg,newPoly.poly); 
     } 
    } 




    System.out.println("Addition completed"); 


    killFirst(newPoly); 
    newPoly = reverse(newPoly); 
    killFirst(newPoly); 
    return newPoly; 
} 









/** 
* Returns the polynomial obtained by multiplying the given polynomial p 
* with this polynomial - DOES NOT change this polynomial 
* 
* @param p Polynomial with which this polynomial is to be multiplied 
* @return A new polynomial which is the product of this polynomial and p. 
*/ 
public Polynomial multiply(Polynomial p) 
{ 
    Polynomial newPoly = new Polynomial(); 

    newPoly.poly = new Node(0,0,null); 

    Node curr = this.poly; 
    Node curr2 = p.poly; 
    Polynomial tempPoly = new Polynomial(); 

    //for(curr=this.poly;curr!=null;curr=curr.next) 
    while(curr!=null) 
    { 
     float x1 = curr.term.coeff; 
     int y1 = curr.term.degree; 
     tempPoly.poly = new Node(0,0,null); 

     while(curr2!=null) 
     { 
      float x2 = curr2.term.coeff; 
      int y2 = curr2.term.degree; 

      addToFront(x1*x2, y1+y2, tempPoly.poly); 
      newPoly = newPoly.add(tempPoly); 
      curr2=curr2.next; 
     } 
     curr=curr.next; 
    } 

    return newPoly; 
} 


/** 
* Evaluates this polynomial at the given value of x 
* 
* @param x Value at which this polynomial is to be evaluated 
* @return Value of this polynomial at x 
*/ 



public Polynomial reverse(Polynomial p) 
{ 
    Polynomial newPoly = new Polynomial(); 
    newPoly.poly = new Node(p.poly.term.coeff,p.poly.term.degree,newPoly.poly); 
    while(p.poly!=null) 
    { 
     addToFront(p.poly.term.coeff,p.poly.term.degree,newPoly.poly); 
     p.poly=p.poly.next; 
    } 
    return newPoly; 
} 

public void killFirst(Polynomial p) 
{ 
    p.poly = p.poly.next; 
} 



public float evaluate(float x) 
{ 
    Node curr = this.poly; 

    int hornerCount = 1; 

    float horner = x; 

    float sum = 0; 
    while(curr!=null) 
    { 
     if(curr.term.degree==0) 
     { 
      sum = sum + curr.term.coeff; 
     } 
     else if(curr.term.degree==1) 
     { 
      sum = sum+(curr.term.coeff*horner); 
     } 
     else if(curr.term.degree>hornerCount) 
     { 
      for(int i=0;i<curr.term.degree-hornerCount;i++) 
      { 
       horner = horner*x; 
      } 
      System.out.println("horner ="+horner); 
      sum = sum+(curr.term.coeff*horner); 
      hornerCount = curr.term.degree; 
     } 
     curr=curr.next; 
     System.out.println("+ "+sum); 
    } 

    return sum; 
} 


/* (non-Javadoc) 
* @see java.lang.Object#toString() 
*/ 
public String toString() { 
    String retval; 

    if (poly == null) { 
     return "0"; 
    } else { 
     retval = poly.term.toString(); 
     for (Node current = poly.next ; 
     current != null ; 
     current = current.next) { 
      retval = current.term.toString() + " + " + retval; 
     } 
     return retval; 
    } 
} 

private void sort(Node head)          // CURRENTLY BROKEN!!!!!!!!!! 
{ 
    Node temp; 
    Node prev; 
    Node curr = head; 
    while(curr.next != null) 
    { 
    if(curr.term.degree < curr.next.term.degree) // deg is smaller or greater 
     {//swap 
      temp = curr; //save first element 
      curr = curr.next; //set first element to second 
      temp.next = curr.next; //set next of first to third 
      curr.next = temp; //set second element to the first that we saved before 
     } 
    prev = curr; 
    curr = curr.next; //move to next element 
    } 
} 

private void addToFront(float coeff, int deg, Node head) 
{ 
    // System.out.println("Hello"); 

    if(head==null) 
    { 
     System.out.println("List empty, creating new node"); 
     head = new Node(coeff,deg,head); 
     System.out.println(head.term.coeff); 
    } 
    else 
    { 
     Node n = new Node(coeff, deg, head.next); 
     // System.out.println(n.term.coeff + " and "+ n.term.degree); 
     head.next = n; 
    } 


} 
+0

會創建一個sentinel頭節點來解決問題嗎? – arunmoezhi 2014-09-25 22:23:48

回答

0

的問題是,addToFront調用方不知道的head的值的方法內改變,因爲head是一個局部變量。調用者只能看到傳遞對象的屬性是否改變。

這是如何工作的(在一個簡化的例子):

步驟1:函數調用之前:

 myObject          Object.name Object.whatever 
+---------------+---------------+---------------+---------------+---------------+ 
|  4  |    |    |  name  | whatever | 
+---------------+---------------+---------------+---------------+---------------+ 
     1    2    3    4    5 
     |            ^
     +-----------------------------------------------+ 

myObject參考位於在RAM ADRESS 1。該引用說:「myObject的屬性在地址4以後」。

第2步:在與非空參數的函數調用:

myObject   head       Object.name Object.whatever 
+---------------+---------------+---------------+---------------+---------------+ 
|  4  |  4  |    |  name  | whatever | 
+---------------+---------------+---------------+---------------+---------------+ 
     1    2    3    4    5 
     |    |        ^
     |    +-------------------------------+ 
     |            ^
     +-----------------------------------------------+ 

當你調用addToFront,新的地址將被分配給該參考head,因爲頭是一個對象。在這種情況下,地址2被指定爲參考head。地址2現在說:「head的屬性在地址4以後」。

這就是爲什麼它會影響調用者,如果傳遞對象的屬性發生更改。如果head要更改其name屬性,則地址​​4將被更改。如果稍後調用myObject.name,則地址4的內容仍將設置爲新值。

第3步:在函數調用空參數

myObject   head 
+---------------+---------------+---------------+---------------+---------------+ 
|  null  |  null  |    |    |    | 
+---------------+---------------+---------------+---------------+---------------+ 
     1    2    3    4    5 

在地址1至myObject參考只是說:「有沒有對象,屬性是無門」。這會被複制到head

第4步:只是功能

myObject   head       Object.name Object.whatever 
+---------------+---------------+---------------+---------------+---------------+ 
|  null  |  4  |    |  name  | whatever | 
+---------------+---------------+---------------+---------------+---------------+ 
     1    2    3    4    5 
         |        ^
         +-------------------------------+ 

當事情被分配到一個局部對象變量之前退出,只是局部變量的引用在RAM更新,但原來的基準不會改變。由於局部變量中的新引用未被複制回原始變量,因此您的函數調用不能按預期執行。


爲了解決你的問題,我提出了兩種選擇:

1.總是返回頭的地方給它分配:

方法簽名:public Node addToFront(...)

致電:newPoly.poly = addToFront(co,deg,newPoly.poly);

這是有效的,因爲將head中的新引用返回並指派給原始引用就像自動將已更改的引用複製回原始引用。

2山口Polynom對象,而不是Node對象

方法簽名:public void addToFront(float coeff, int deg, Polynom polynom)

在方法的一開始就加入這一行:Node head = polynom.poly;

這可能意味着,你不能在某些地方按預期使用該方法。在任何時候檢查你是否通過其他方法將somePolynom.poly傳遞給方法。如果是這種情況,你不能使用這種方法。

這是有效的,因爲head的內容不是局部變量(即參數),而是傳遞對象的屬性。