2012-08-01 68 views
1

現在正在使用Java來處理此項目一段時間。建議我爲我的程序使用鏈接列表或數組列表,這非常合理。然而,教授說我們必須製作和使用我們自己的鏈接列表利用節點。儘管在課堂上進行了一些研究和問詢,但與Nodes合作讓我感到非常困惑。我確信這是一件簡單的事情,但我現在處於完全失落狀態。這是列表存儲的類(我認爲)。它被稱爲飛機,因爲我們正在創建一個列表來存儲多架飛機和一些與它們相關的細節(飛行名稱,速度,高度,飛機類型)。我有一個用戶與之交互的主類(未列出) - 我已經很熟悉這個類。僅使用節點創建Java鏈接列表的幫助

package airTraffic; 

public class Aircraft { 

public static String name; 
public static String type; 
public static int speed; 
public static int alt; 

Aircraft nextCraft; 

public Aircraft (String n, String t, int s, int a) { 
    name = n; 
    type = t; 
    speed = s; 
    alt = a; 
} 

public Aircraft() { 

} 

public static void setName(String n) { 
    name = n; 
} 

public static String getName (String lookUp) { 
    return name; 
} 

public static void removeName() { 
    //remove the flight - not sure what to place here 
} 

public static void setType (String t) { 
    type = t; 
} 

public static String getType() { 
    return type; 
} 

public static void setSpeed (int s) { 
    speed = s; 
} 

public static int getSpeed() { 
    return speed; 
} 

public static void setAlt(int a) { 
    alt = a; 
} 

public static int getAlt() { 
    return alt; 
} 

public Aircraft next = null; 

//auto generated method from ATControl 
public static void add(String s) { 

} 

//auto generated methods from ATControl - what goes here??? 
public static void remove() { 

} 

public Object getNext() { 
    // TODO Auto-generated method stub 
    return null; 
} 

public void setNext(Object next2) { 
    // TODO Auto-generated method stub 

} 
} 

下面,我有我認爲是創建和存儲節點的類。這是我非常困惑,並認爲我錯了。我不知道如何調用節點來實際添加和存儲數據。我還需要能夠獲得的節點(通過飛行名),並刪除該節點(通過飛行名)

package airTraffic; 

import java.util.*; 
import airTraffic.Aircraft; 

public class ATControl { 


static Main m = new Main(); 
Aircraft aircraft = new Aircraft(); 

//declare node names for list 
public static Aircraft head = new Aircraft(); 
public static Aircraft tail = new Aircraft(); 

// stores data 
private static final int INITIAL_ALLOCATION = 20; 
private static int size = INITIAL_ALLOCATION; 

// tells list to add nodes 
public static void Nodes (String s, int n) { 
    n = size; 
    head.next = tail; 
    tail.next = tail; 
    Aircraft temp = head; 
    for (int i= 0; i < size; ++i) { 
     temp.next = new Aircraft(); 
     temp = temp.next; 
    } 
    temp.next = tail; 
} 

public static void addNodes (int n) { 
    n = size; 
    Aircraft temp = new Aircraft(); 
    Aircraft current = head; 
    for (int i = 1; i < n && current.getNext() != null; i++) { 
     current = (Aircraft) current.getNext(); 
     temp.setNext(current.getNext()); 
     current.setNext (temp); 
     size++; 
    } 
} 

//add plane and details 
public static void addToList (Scanner in) { 
    // should add new aircraft to new node on linked list 
    System.out.printf("Enter flight number: "); 
    String add = in.next(); 
    Aircraft.setName (add); 
    ATControl.addNodes (Integer.parseInt(add)); 

    //type of plane 
    System.out.printf("Enter type of plane: "); 
    String plane = in.next(); 
    Aircraft.setType (plane); 

    //plane speed 
    System.out.printf("Enter current speed: "); 
    int speed = in.nextInt(); 
    Aircraft.setSpeed (speed); 
    ATControl.addNodes (Integer.parseInt(add)); 


    //add Altitude 
    System.out.printf("Enter current altitude: "); 
    int alt = in.nextInt(); 
    Aircraft.setAlt(alt); 
    ATControl.addNodes (Integer.parseInt(add)); // I am fairly certain this is wrong 
} 

//show flight 
public static void showFlight (Scanner in) { 
    System.out.printf("Enter flight number for details: "); 
    String lookUp = in.next(); 
    Aircraft.getName(lookUp); 

} 
// display all flights 
public static void displayAll (Scanner in) { 
    System.out.printf("All flights: "); 

} 
//remove flight 
public static void removeFlight (Scanner in) { 
    System.out.printf("Enter flight number to be removed: "); 

} 
} 

回答

0

公共類節點{

public int item; 
    public Node next; 
    public Node tail; 


    Node() {     
     item = 0; 
     next = null; 
     tail = null ;  
    } 

    Add Node(node tail, node new) { 

     tail.next = new; 
     tail.tail = new 
     new.tail =null 

    } 

};

我希望我沒有讓事情變得更糟。祝你好運。

飛機類可以擴展節點類。看看java中的childfactory類。它會給你一個你將在節點類中使用的方法類型的例子。重新思考你的課程。也許刪除Airplane將是節點類中的一種方法,如刪除節點。任何在節點上工作的東西,比如插入或添加新的,刪除和排序都可以添加到節點類中。然後,您可以在添加更多類時重用此類。

http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

1

我覺得你已經很接近 - 但它很難說究竟是怎麼回事你ATControl類。通常,鏈表上的add方法需要一個節點(在你的情況下是飛機),而不是數字。

鏈接列表的關鍵是每個節點都有一個指向列表中下一個的指針。在你的飛機艙中,你有:飛機下一個,它將作爲指針。

我建議在實施的ATControl以下方法:

public static Aircraft getUserInput(Scanner in) 
{ 
    Aircraft aircraft = new Aircraft(); 

    // get your values from the user and set them in your new aircraft 
    return aircraft; 
} 

public static void add(Aircraft aircraft) 
{ 
    // starting at head, walk through the list (repeatedly call next on 
    // the current Aircraft) until you reach the desired position 

    Aircraft temp = head; 

    while (temp != null) // ... 
} 

public static void remove(String flightNum) 
{ 
    // again, the same way you did in add, walk through the list until you find it 
    if (current.getName().equals(flightNum)) 
     // we found it, so remove it 
} 
2

你越來越接近。首先鏈表是一個對象列表,通常稱爲節點,每個節點都有一個或多個指向其他對象的鏈接。在你的情況下,節點是飛機。

這會幫助你一下:Wikipedia:Linked List

你的主要問題到目前爲止是,你不必在你的飛機類的鏈接。由於這是一個鏈表,因此您需要在列表中包含對下一個元素的引用。在Aircraft類中,您應該有一個名爲next的飛機類型屬性,將您鏈接到列表中的下一架飛機。這允許您撥打myAircraft.next,因爲您目前在代碼中,這將允許您按順序在列表中下移。我會讓你自己找出其餘的,這是作業,但如果你需要更多的解釋,隨時發表評論。

0

這裏是一個鏈接,當他們說一個列表時,思考者提到了什麼。這是鏈接http://www.algolist.net/Data_structures/Singly-linked_list/Traversal,解釋列表。不過,我不確定這在java中是否具有代表性。你寫的代碼看起來像你沒有排序,但在列表的最後添加了所有飛機。因此該列表未被排序。當你讓temp.next = tail使列表中的最後一架飛機指向自身而不是null時。但是你不檢查空值,你正在計算列表中的飛機數量。我發佈了一個java示例,其中您有一個節點類,下一個節點,您應該添加節點尾,因爲您的代碼正在使用它。

1

除非您非常牢固地掌握OOP和引用類型,否則試圖編寫LinkedList實現是一種在受虐狂中的做法。

以下將會很長,可能會痛苦/羞辱。沒關係,這將是一次很好的學習經歷。我在這方面付出了很多努力,提供了徹底的評論和完整的實施。我建議你仔細閱讀細節,直到你完全理解他們的目的。

首先,修好你的飛機班。既然你需要創建多個實例,靜態成員將無法工作。如果你不明白爲什麼,花一些時間來刷新你的面向對象的基礎知識。

列表節點應設計爲存儲最少的數據。在你的情況下,它看起來就像你在那裏的大部分。有針對每個節點的航班數據和對列表中下一個項目的引用。這就是你需要的。

如果沒有這些額外的克魯夫特這裏是什麼樣子:

public class Aircraft { 
    public String name; 
    public String type; 
    public int speed; 
    public int alt; 
    Aircraft next; 

    public Aircraft (String n, String t, int s, int a) { 
     name = n; 
     type = t; 
     speed = s; 
     alt = a; 
     next = null; 
    } 
} 

看起來不錯。假設這具有內置的所有必要功能是安全的。

如果你想隨意添加以下回復於:

  • 的setName()
  • 的getName()
  • 的setType()
  • 的getType()
  • setSpeed( )
  • getSpeed()
  • setAlt()
  • getAlt()

注:如果他們不設置爲靜態,這隻會工作。除非你打算通過飛機實例被更改作爲參數之一,每次你打電話給它。相信我,使用實例方法要容易得多。

變化:

  • 我刪除了飛機()構造。至少,您需要使用至少一個航班號(或其他唯一標識符)初始化一個飛機節點,否則您將不能在稍後的列表中找到飛機。

  • removeName()是無用的。由於單個節點只知道列表中的下一個項目,因此它們無法自行刪除。如果您使用了雙向鏈接列表,其中每個節點都存儲對之前的下一個節點的引用,那麼這將是可能的,但實際上並不需要。 add()remove()*方法也是如此。添加/清除在** ATControl類中處理。

  • 沒有太多需要GETNEXT()setNext()無論是。由於ATControl用於維護列表的狀態(例如,大小,容量等),您不希望通過獲取者/設置者公開訪問nextCraft

現在對於ATControl:

public class ATControl { 
    private Aircraft head; // stores the start of the chain 
    private Aircraft tail; // stores the end of the chain 
    private int size; // stores the length of the chain 

    public ATControl() { 
     // ♫ "Started from the bottom now we're herre' ♫ 
     // Seriously, the list should start with nothing 
     head = null; 
     tail = null; 
     size = 0; 
    } 

    public void addFlight(String flight, String plane, int speed, int alt) { 
     // TODO: Implement this 
    } 

    public void removeFlight(String name) { 
     // TODO: Implement this 
    } 

    public void displayFlight(String name) { 
     // TODO: Use a foreach loop to find and display a flight 
    } 

    public void displayAll() { 
     // TODO: Use a foreach loop to display the flights here 
    } 
} 

變化:

  • 我刪除了主*員,因爲我沒有絲毫的想法如何運作這裏。無論哪種方式,要使用這個,你需要創建一個新的** ATControl實例。

  • 我刪除了內聯變量聲明,因爲它的實例成員必須在構造函數中設置。

  • 被初始化爲null,因爲沒有飛機已被添加。

  • 我刪除了飛機成員,因爲它永遠不會被使用。

  • 除非你只希望創建一個ATControl情況下,你不應該設置太靜態兩種。如果它們中的任何一個都被ATControl改變了,它會搞砸列表的內部狀態,所以它們應該被設置爲私有。

  • 我刪除了大小限制,因爲它沒有必要做這個工作。如果需要,您可以稍後將其添加回來。

  • 我砍掉節點()addNodes()有兩個原因。首先,它違反了SRP(單一責任原則),因爲它們負責創建一個節點和一組節點。其次 - 我假設這是一個錯誤,但是 - 您要將航班號傳遞給您想要創建的節點數。例如,如果航班號是1457,那麼你會在列表中添加1457個空節點。

  • 我改名addToList()addFlight(),以保持一致性。我還將其更名爲showFlight()displayFlight()以保持一致性。爲了簡單起見,爲了使這個類不僅僅是命令行輸入,我還刪除了用戶輸入部分。


我知道,我知道!我是一個無情的屠夫,但現在代碼處於一個很好的位置,可以開始建立必要的功能。

第一件事第一件事。如果你不知道讓一個類可迭代(即作爲一個foreach循環工作),你將會發現。我需要添加更多的東西到ATControl,但它會很有趣。

public class ATControl implements Iterable { 
    private Aircraft head; 
    private Aircraft tail; 
    private int size; 

    public ATControl() { 
     head = null; 
     tail = null; 
     size = 0; 
    } 

    public void addFlight(String flight, String plane, int speed, int alt) { 
     // if the list is not currently empty 
     if (!isEmpty()) { 
      // store a reference to the last Aircraft in the list 
      Aircraft prev = tail; 
      // create a new aircraft and add it to the end of the list 
      tail = new Aircraft(flight, plane, speed, alt); 
      // link the old tail to the new tail 
      prev.next = tail; 
     } 
     // an empty list needs to be handled a little differently 
     else { 
      // notice, with no tail there's no tail to update 
      tail = new Aircraft(flight, plane, speed, alt); 
      // also, since there's only one item the head and tail are the same 
      head = tail; 
     } 
     size++; 
    } 

    // The hard part. Lots of nasty edge cases. 
    // Creating one of these from scratch will make your head hurt. 
    // Note: Setting variables to null marks them for the garbage collector. 
    // SideNote: With a doubly-linked list you can do removals within a foreach loop 
    public void removeFlight(String flight) { 
     Node prev = head; 
     Node curr = head; 
     // crawl the list looking for a match 
     while (curr.next != null || curr == tail) { 
      if (curr.flight.equals(flight)) { 
       // if there is only one item left, null everything 
       if (size == 1) { head = null; tail = null; } 
       // reset the head to start at the second Aircraft 
       else if (curr.equals(head)) { head = head.next; } 
       // reset the tail to end at the 2nd-to-last Aircraft 
       else if (curr.equals(tail)) { tail = prev; tail.next = null; } 
       // if it's in the middle, re-connect the broken links on either end 
       else { prev.next = curr.next; } 
       size--; 
       break; 
      } 
      prev = curr; 
      curr = prev.next; 
     } 
    } 

    public boolean isEmpty() { 
     return size == 0; // only returns true if size is 0 

    // The fun part. The following are necessary to make the list iterable 
    // Like magic, this class will now be callable as a foreach loop 
    public Iterator<Aircraft> iterator() { return new ATCIterator(); } 

    // This iterator code can be reused on any linked-list implementation 
    // Keep this handy in case you need to implement Iterable in the future 
    private class ATCIterator implements Iterator<Aircraft> { 
     private Aircraft current = head; 

     public Aircraft next() { 
      if (!hasNext()) { throw new NoSuchElementException(); } 
      Aircraft aircraft = current; 
      current = current.next; 
      return aircraft; 
     } 

     public boolean hasNext() { return current != null; } 

     // inline removals require a doubly linked list. To reconnect the break 
     // in the chain the node has to be aware of both the previous and next nodes. 
     public void remove() { throw new UnsupportedOperationException(); } 
    } 

    // lets put that foreach loop functionality to good use now. 

    // Bonus: use this to retrieve the matching Aircraft instance 
    // Once you have a reference to the Aircraft instance you can do things like 
    // get/set it's internal values. 
    public aircraft getFlight(String flight) { 
     for (Aircraft aircraft : this) 
      if (this.flight == flight) { 
       return this; 
    } 


    // displays the flight number of the first match 
    public void displayFlight(String flight) { 
     for (Aircraft aircraft : this) 
      if (this.flight == flight) { 
       System.out.printf("Flight: " + flight); 
       // Note: you can access the Aircraft details here via the 'this' keyword 
       return; 
    } 

    // crawls the whole list and displays the flight number of every aircraft 
    public void displayAll() { 
     for (Aircraft aircraft : this) 
      System.out.printf("Flight: " + flight); 
      // Note: you can access the flight details here via the 'this' keyword 
    } 
} 

所以,你的代碼有很多的意見終日啃食在牆上。一些理論的時間。

什麼讓LinkedList成爲LinkedList?

這實際上只是一堆對象實例,它們隨機放置在堆上並通過引用(或針對C人羣的指針)鏈接在一起。

想象一個LinkedList作爲桑巴線

Samba Line

來源:The Traveling Eye Blog

注:雙向鏈表,除了線可以改變方向相同。

每個人都緊盯着他們面前的人,但他們看不到他們身後的人。添加到列表就像添加一個人到行的前面。從技術上講,我寫的LinkedList作品的方向相反,添加的內容被添加到前端,刪除從尾部刪除,但概念是相同的。

從列表中提取/刪除項目就像添加一個limbo杆。第一擊從鏈條中取出,休息通過重新連接休息的兩端來修補。

使用LinkedList的好處是它可以像你想要的一樣大或小。然而,你可以自由地添加/刪除節點。

不利之處在於,與數組不同,如果沒有先行鏈接鏈接,就無法從列表中獲取項目。而且,當列表變得非常大時,所有這些類實例和引用的開銷開始變得昂貴。

在性能方面,需要O(1)(即恆定時間)來添加項目。 O(N)(即線性時間)從列表中提取/刪除項目。並且,根據列表是單/雙和/或跳轉鏈接,涉及顯着的內存開銷。

還有其他的數據結構,如ArrayLists,HashMaps等,它們對像您這樣的用例具有更好的性能或內存特性,但它們的編寫/管理更加複雜。

在沒有工作的情況下獲得高級數據結構的所有神奇功能的最簡單方法是打包和擴展現有的實現。例如,您可以創建一個在內部使用ArrayList進行數據存儲的類。你甚至可以使用我上面演示的方法進行迭代。除了不是爲任何通用類型編寫的,它可以定製爲使用您的飛機數據類型。

注意:如果您想學習如何編寫數據結構,我建議您在線(或以其他方式)學習算法I類。

+0

好答案.. +1 – 2014-02-24 09:16:29