2010-11-01 76 views
30

我們被賦予了一個從頭開始創建一個LinkedList的任務,並且絕對沒有任何讀數可以指導我們完成這個導致遷移的任務。網上的一切似乎只是使用Java內置的LinkedList方法和東西。無論如何,鏈接列表在使用Java的默認東西時非常有意義,但是從頭開始創建它毫無意義。可以說我有從零開始創建一個LinkedList類

public class LinkedList { 
    private LinkedList next; 
    private final String word; 
    // constructor 
    public LinkedList(String word, LinkedList next) { 
    this.word = word; 
    this.next = next; 
    } 

因此神奇地我們有一個鏈表。到底是怎麼回事?我如何創建這樣的鏈表?這個怎麼用?我應該編寫一個附加方法,將給定的String word參數添加到this鏈接列表的末尾。我嘗試着查看內置java中的鏈接列表類的addLast內置方法,但這對我沒有任何幫助,因爲我真的不知道發生了什麼。任何人都在幫助我:)

回答

38

如果你實際上建立一個真正的系統,那麼,你通常只是使用的東西,在標準庫,如果你需要的是可以有。也就是說,不要認爲這是毫無意義的練習。理解事物如何工作是很好的,理解鏈表是理解更復雜的數據結構的重要步驟,其中許多數據結構在標準庫中不存在。

創建鏈接列表的方式與Java集合API執行方式有一些區別。 Collections API試圖堅持更復雜的界面。 Collections API鏈接列表也是一個雙向鏈接列表,而您正在構建單個鏈接列表。你在做什麼更適合於班級任務。

使用您的LinkedList類,實例將始終是至少一個元素的列表。有了這種設置,當你需要一個空的列表時,你會使用null

認爲next是「列表中的其餘部分」。實際上,許多類似的實現使用名稱「尾部」而不是「下一個」。

這裏的一個LinkedList含有3種元素的示圖:

linked list diagram

注意,它是指向一個字(「你好」)一個LinkedList對象和2個元素的列表。 2個元素的列表包含一個單詞(「堆棧」)和1個元素的列表。 1元素的列表包含一個單詞(「Overflow」)和一個空列表(null)。因此,您可以將next視爲恰好是一個元素更短的另一個列表。

你可能想要添加另一個只需要一個字符串的構造函數,並且設置在null旁邊。這將用於創建1元素列表。

要追加,請檢查next是否爲null。如果是,則創建一個新的元素列表並將其設置爲next

next = new LinkedList(word); 

如果未來不null,然後附加到next代替。

next.append(word); 

這是遞歸方法,它是最少量的代碼。你可以把它變成一個迭代的解決方案,它將在Java *中更高效,並且不會冒着很長列表的堆棧溢出的風險,但我猜測你的任務不需要複雜程度。


*有些語言有尾調用消除,這是一個讓語言實現優化轉換「尾調用」(另一種功能爲返回前的最後一步的調用)到(有效)一「去」。這使得這樣的代碼完全避免使用堆棧,這使得它更安全(如果你不使用堆棧,你不能溢出堆棧)並且通常更高效。 Scheme可能是具有此功能的語言中最着名的示例。

+0

好的遞歸方法是我需要的,但我不完全理解它是如何工作的。所以如果它爲空,那麼任務很簡單。如果沒有,我們再次運行追加。如果next.next == null?我沒有明白,這是如何工作的? – Snowman 2010-11-01 05:27:34

+1

如果'next.next == null'則表明下一個不是'null'。所以你叫'next.append(word)'。現在我們處於what-was-'-next'的'append'方法。所以我們現在稱之爲'this'就是我們之前稱之爲'next'的東西。我們看'next'(我們以前會叫'next.next'),它是'null',所以我們設置'next = new LinkedList(word)'。 – 2010-11-01 05:36:55

1

我是如何創建這樣的鏈表的。這個怎麼用? 這是一個鏈接列表。一個鏈接到列表中下一個項目的項目。只要您在列表的開頭保留對該項目的引用,就可以使用每個後續引用指向下一個值來遍歷整個事物。

要追加,您只需查找列表的末尾,然後將下一個項目添加爲您要添加的值,因此如果下一個項目非空,則必須在下一個項目上調用append直到找到列表的末尾。

this.next.Append(word); 
+0

等等..什麼?所以我會設置next = word?我如何讓最後一項與我的單詞相同?這是令我困惑的。這是如何指定的? – Snowman 2010-11-01 05:13:48

+0

不,你會發現最後一個項目定義爲'next == null',並在該對象上設置'next = new LinkedList(word,null);'。 – 2010-11-01 05:16:01

+0

哦,好吧,我明白了。但是在創建append方法的方法的描述中,它說:「遞歸地查找最後一個條目,然後在末尾添加一個新鏈接。」爲什麼我需要遞歸地找到它,當我可以說'if(next == null)'? – Snowman 2010-11-01 05:19:26

5

當然,鏈接列表對於編程n00bs有點困惑,幾乎所有的誘惑都是將它視爲俄羅斯娃娃,因爲它就像是LinkedList對象中的LinkedList對象。但這是一種難以形象化的觸摸,而是像電腦一樣來看待它。

的LinkedList =數據+接下來會員

如果它是列表的最後一個成員,如果下一個是NULL

所以5元LinkedList的是:

鏈表(數據1,鏈表(數據2,鏈表(數據3,鏈表(數據4,鏈表(數據5,NULL)))))

但是你可以簡單地認爲它:

數據1 - >大ta2 - > Data3 - > Data4 - > Data5 - > NULL

那麼,我們該如何找到結束呢?好吧,我們知道NULL是結束這樣:

public void append(LinkedList myNextNode) { 
    LinkedList current = this; //Make a variable to store a pointer to this LinkedList 
    while (current.next != NULL) { //While we're not at the last node of the LinkedList 
    current = current.next; //Go further down the rabbit hole. 
    } 
    current.next = myNextNode; //Now we're at the end, so simply replace the NULL with another Linked List! 
    return; //and we're done! 
} 

當然,這是非常簡單的代碼,它無限循環,如果你給它一個循環鏈表!但這是基礎知識。

21

你已經編碼的不是LinkedList,至少不是我認識的一個。對於這項任務,要創建兩個類:

LinkNode 
LinkedList 

一個LinkNode有一個成員字段包含的數據,和LinkNode參考下一LinkNodeLinkedList。是的,這是一個自我參考數據結構。 A LinkedList只是有一個特殊的LinkNode引用,它引用列表中的第一項。

當您在LinkedList中添加項目時,您將遍歷所有的LinkNode's,直到達到最後一個。這LinkNode's接下來應該爲空。然後在這裏構建一個新的LinkNode,設置它的值,並將其添加到LinkedList

public class LinkNode { 

    String data; 
    LinkNode next; 

    public LinkNode(String item) { 

     data = item; 

    } 

} 

public class LinkedList { 

    LinkNode head; 

    public LinkedList(String item) { 

     head = new LinkNode(item); 

    } 

    public void add(String item) { 

     //pseudo code: while next isn't null, walk the list 
     //once you reach the end, create a new LinkNode and add the item to it. Then 
     //set the last LinkNode's next to this new LinkNode 

    } 


} 
8

提示1:http://en.wikipedia.org/wiki/Linked_list

提示2讀鏈表的描述:Java實現的LinkedList的是一個雙向鏈表。你的是一個單獨的鏈表。算法不直接適用。


另外:

...但從頭開始創建[鏈表類]是沒有任何意義。

這取決於所需的結果是什麼。如果目標是生成符合某些功能/非功能需求的代碼,那麼你是對的。如果real的目標是針對你的學習如何編程/設計API /實現非平凡的數據結構,那麼最終產品的效用幾乎完全不相關。

就這樣奇蹟般地我們有一個鏈表

什麼你確實有有一個開放的數據類型,可以用來構建一個(排序)名單。但這不是你的老師想要的。它當然不會被認爲是一個有用的列表抽象。通過有效的抽象將包括:

  • 方法做程序員不想再重複了一遍又一遍的東西,

  • 時停止程序員「破」列表中的一個抽象層;例如無意中創建了一個循環,或者意外地將一個子列表拼接到兩個列表中以創建一個倒轉樹。

+0

1)這不是考試......也有例外。 2)如果你說沒有必要了解單個鏈表,因爲他們沒有在考試中詢問他們:這個任務的真正目標是學習編程和/或數據結構,而不是通過考試。 3)我們還沒有完全知道實際要求的是什麼......而投機是毫無意義的。 4)這與我的回答有什麼關係。這當然是對這個問題的評論。 – 2017-12-20 23:27:13

11

怎麼樣一個全功能的實現非遞歸鏈表?

我爲我的算法I類創建了這個作爲踏腳石以獲得更好的理解,然後再編寫雙向鏈接的隊列類作業。

下面的代碼:

import java.util.Iterator; 
import java.util.NoSuchElementException; 

public class LinkedList<T> implements Iterable<T> { 
    private Node first; 
    private Node last; 
    private int N; 

    public LinkedList() { 
     first = null; 
     last = null; 
     N = 0; 
    } 

    public void add(T item) { 
     if (item == null) { throw new NullPointerException("The first argument for addLast() is null."); } 
     if (!isEmpty()) { 
      Node prev = last; 
      last = new Node(item, null); 
      prev.next = last; 
     } 
     else { 
      last = new Node(item, null); 
      first = last; 
     } 
     N++; 
    } 

    public boolean remove(T item) { 
     if (isEmpty()) { throw new IllegalStateException("Cannot remove() from and empty list."); } 
     boolean result = false; 
     Node prev = first; 
     Node curr = first; 
     while (curr.next != null || curr == last) { 
      if (curr.data.equals(item)) { 
       // remove the last remaining element 
       if (N == 1) { first = null; last = null; } 
       // remove first element 
       else if (curr.equals(first)) { first = first.next; } 
       // remove last element 
       else if (curr.equals(last)) { last = prev; last.next = null; } 
       // remove element 
       else { prev.next = curr.next; } 
       N--; 
       result = true; 
       break; 
      } 
      prev = curr; 
      curr = prev.next; 
     } 
     return result; 
    } 

    public int size() { 
     return N; 
    } 

    public boolean isEmpty() { 
     return N == 0; 
    } 

    private class Node { 
     private T data; 
     private Node next; 

     public Node(T data, Node next) { 
      this.data = data; 
      this.next = next; 
     } 
    } 

    public Iterator<T> iterator() { return new LinkedListIterator(); } 

    private class LinkedListIterator implements Iterator<T> { 
     private Node current = first; 

     public T next() { 
      if (!hasNext()) { throw new NoSuchElementException(); } 
      T item = current.data; 
      current = current.next; 
      return item; 
     } 

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

     public void remove() { throw new UnsupportedOperationException(); } 
    } 

    @Override public String toString() { 
     StringBuilder s = new StringBuilder(); 
     for (T item : this) 
      s.append(item + " "); 
     return s.toString(); 
    } 

    public static void main(String[] args) { 
     LinkedList<String> list = new LinkedList<>(); 
     while(!StdIn.isEmpty()) { 
      String input = StdIn.readString(); 
      if (input.equals("print")) { StdOut.println(list.toString()); continue; } 
      if (input.charAt(0) == ('+')) { list.add(input.substring(1)); continue; } 
      if (input.charAt(0) == ('-')) { list.remove(input.substring(1)); continue; } 
      break; 
     } 
    } 
} 

注:這是一個非常基本實現單鏈接列表中。 'T'類型是一個通用類型的佔位符。基本上,這個鏈表應該適用於從Object繼承的任何類型。如果您將它用於基本類型,請確保使用可空類對應(如'Integer'用於'int'類型)。除了縮短O(1)時間的插入之外,'最後'變量不是必須的。因爲它們以O(N)時間運行,所以刪除速度很慢,但它允許您刪除列表中第一次出現的值。

如果你願意,你也可以考慮實施:

  • addfirst僅() - 增加一個新項目LinkedList的
  • removeFirst()的開始 - 從LinkedList的
  • 取出的第一個項目
  • removeLast() - 從鏈表
  • 的addAll()刪除最後一個項目 - 項目的列表/陣列添加到鏈表
  • 的removeAll() - 刪除項目的列表/陣列從LinkedList的
  • 包含S() - 檢查,看看是否LinkedList的包含項目
  • 包含() - 清除LinkedList的所有項目

老實說,只需要的幾行代碼來使這是一個雙向鏈表。這和雙鏈表之間的主要區別在於,雙鏈表的Node實例需要一個額外的引用來指向列表中的前一個元素。

這對遞歸實現的好處是速度更快,並且在遍歷大型列表時不必擔心氾濫堆棧。

有3個命令在調試器/控制檯來測試:通過「+」將其添加到列表

  • 加前綴的值。
  • 用' - '前綴將從列表中刪除第一個匹配項。
  • 輸入'print'將打印列表,其中值以空格分隔。

如果你從來沒有見過的內部如何將這些作品,我建議你通過在調試器以下步驟之一:

  • 的add() - 大頭針一個新的節點到年底或初始化如果列表爲空,則爲第一個/最後一個值
  • remove() - 從頭到尾遍歷列表。如果找到匹配項,則刪除該項目並連接鏈中上一鏈接和下一鏈接之間的斷開鏈接。沒有上一個或下一個鏈接時會添加特殊例外。
  • toString() - 使用foreach迭代器簡單地從頭到尾遍歷列表鏈。

雖然有像數組列表列出了更好,更有效的方法,理解應用程序如何通過遍歷引用/指針是不可或缺的理解許多更高級別的數據結構是如何工作的。

-1
class Node 
{ 
    int data; 
    Node link; 

    public Node() 
    { 
     data=0; 
     link=null; 
     } 

    Node ptr,start,temp; 

    void create()throws IOException 
    { 
     int n; 
     BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); 
     System.out.println("Enter first data"); 
     this.data=Integer.parseInt(br.readLine()); 
     ptr=this; 
     start=ptr; 
     char ins ='y'; 
     do 
     { 
      System.out.println("Wanna Insert another node???"); 
      ins=(char)br.read(); 
      br.read(); 
      if(ins=='y') 
      { 
       temp=new Node(); 
       System.out.println("Enter next data"); 
       temp.data=Integer.parseInt(br.readLine()); 
       temp.link=null; 
       ptr.link=temp; 
       temp=null; 
       ptr=ptr.link; 
       } 
      }while(ins=='y'); 
     } 

public static void main(String args[])throws IOException 
    { 
     Node first= new Node(); 
     first.create(); 
} 
} 
0

請閱讀這篇文章:How To Implement a LinkedList Class From Scratch In Java

package com.crunchify.tutorials; 

/** 
* @author Crunchify.com 
*/ 

public class CrunchifyLinkedListTest { 

    public static void main(String[] args) { 
     CrunchifyLinkedList lList = new CrunchifyLinkedList(); 

     // add elements to LinkedList 
     lList.add("1"); 
     lList.add("2"); 
     lList.add("3"); 
     lList.add("4"); 
     lList.add("5"); 

     /* 
     * Please note that primitive values can not be added into LinkedList 
     * directly. They must be converted to their corresponding wrapper 
     * class. 
     */ 

     System.out.println("lList - print linkedlist: " + lList); 
     System.out.println("lList.size() - print linkedlist size: " + lList.size()); 
     System.out.println("lList.get(3) - get 3rd element: " + lList.get(3)); 
     System.out.println("lList.remove(2) - remove 2nd element: " + lList.remove(2)); 
     System.out.println("lList.get(3) - get 3rd element: " + lList.get(3)); 
     System.out.println("lList.size() - print linkedlist size: " + lList.size()); 
     System.out.println("lList - print linkedlist: " + lList); 
    } 
} 

class CrunchifyLinkedList { 
    // reference to the head node. 
    private Node head; 
    private int listCount; 

    // LinkedList constructor 
    public CrunchifyLinkedList() { 
     // this is an empty list, so the reference to the head node 
     // is set to a new node with no data 
     head = new Node(null); 
     listCount = 0; 
    } 

    public void add(Object data) 
    // appends the specified element to the end of this list. 
    { 
     Node crunchifyTemp = new Node(data); 
     Node crunchifyCurrent = head; 
     // starting at the head node, crawl to the end of the list 
     while (crunchifyCurrent.getNext() != null) { 
      crunchifyCurrent = crunchifyCurrent.getNext(); 
     } 
     // the last node's "next" reference set to our new node 
     crunchifyCurrent.setNext(crunchifyTemp); 
     listCount++;// increment the number of elements variable 
    } 

    public void add(Object data, int index) 
    // inserts the specified element at the specified position in this list 
    { 
     Node crunchifyTemp = new Node(data); 
     Node crunchifyCurrent = head; 
     // crawl to the requested index or the last element in the list, 
     // whichever comes first 
     for (int i = 1; i < index && crunchifyCurrent.getNext() != null; i++) { 
      crunchifyCurrent = crunchifyCurrent.getNext(); 
     } 
     // set the new node's next-node reference to this node's next-node 
     // reference 
     crunchifyTemp.setNext(crunchifyCurrent.getNext()); 
     // now set this node's next-node reference to the new node 
     crunchifyCurrent.setNext(crunchifyTemp); 
     listCount++;// increment the number of elements variable 
    } 

    public Object get(int index) 
    // returns the element at the specified position in this list. 
    { 
     // index must be 1 or higher 
     if (index <= 0) 
      return null; 

     Node crunchifyCurrent = head.getNext(); 
     for (int i = 1; i < index; i++) { 
      if (crunchifyCurrent.getNext() == null) 
       return null; 

      crunchifyCurrent = crunchifyCurrent.getNext(); 
     } 
     return crunchifyCurrent.getData(); 
    } 

    public boolean remove(int index) 
    // removes the element at the specified position in this list. 
    { 
     // if the index is out of range, exit 
     if (index < 1 || index > size()) 
      return false; 

     Node crunchifyCurrent = head; 
     for (int i = 1; i < index; i++) { 
      if (crunchifyCurrent.getNext() == null) 
       return false; 

      crunchifyCurrent = crunchifyCurrent.getNext(); 
     } 
     crunchifyCurrent.setNext(crunchifyCurrent.getNext().getNext()); 
     listCount--; // decrement the number of elements variable 
     return true; 
    } 

    public int size() 
    // returns the number of elements in this list. 
    { 
     return listCount; 
    } 

    public String toString() { 
     Node crunchifyCurrent = head.getNext(); 
     String output = ""; 
     while (crunchifyCurrent != null) { 
      output += "[" + crunchifyCurrent.getData().toString() + "]"; 
      crunchifyCurrent = crunchifyCurrent.getNext(); 
     } 
     return output; 
    } 

    private class Node { 
     // reference to the next node in the chain, 
     // or null if there isn't one. 
     Node next; 
     // data carried by this node. 
     // could be of any type you need. 
     Object data; 

     // Node constructor 
     public Node(Object dataValue) { 
      next = null; 
      data = dataValue; 
     } 

     // another Node constructor if we want to 
     // specify the node to point to. 
     public Node(Object dataValue, Node nextValue) { 
      next = nextValue; 
      data = dataValue; 
     } 

     // these methods should be self-explanatory 
     public Object getData() { 
      return data; 
     } 

     public void setData(Object dataValue) { 
      data = dataValue; 
     } 

     public Node getNext() { 
      return next; 
     } 

     public void setNext(Node nextValue) { 
      next = nextValue; 
     } 
    } 
} 

輸出

lList - print linkedlist: [1][2][3][4][5] 
lList.size() - print linkedlist size: 5 
lList.get(3) - get 3rd element: 3 
lList.remove(2) - remove 2nd element: true 
lList.get(3) - get 3rd element: 4 
lList.size() - print linkedlist size: 4 
lList - print linkedlist: [1][3][4][5] 
3

鏈表來展示插件前,在Java中刪除前,插入後和刪除後的操作:

import java.io.DataInputStream; 
import java.io.IOException; 


public class LinkedListTest { 

public static void main(String[] args) { 
    // TODO Auto-generated method stub  
    Node root = null; 

    DataInputStream reader = new DataInputStream(System.in);   
    int op = 0; 
    while(op != 6){ 

     try { 
      System.out.println("Enter Option:\n1:Insert Front 2:Delete Front 3:Insert Rear 4:Delete Rear 5:Display List 6:Exit"); 
      //op = reader.nextInt(); 
      op = Integer.parseInt(reader.readLine()); 
      switch (op) { 
      case 1: 
       System.out.println("Enter Value: "); 
       int val = Integer.parseInt(reader.readLine()); 
       root = insertNodeFront(val,root); 
       display(root); 
       break; 
      case 2: 
       root=removeNodeFront(root); 
       display(root); 
       break; 
      case 3: 
       System.out.println("Enter Value: "); 
       val = Integer.parseInt(reader.readLine()); 
       root = insertNodeRear(val,root); 
       display(root); 
       break; 
      case 4: 
       root=removeNodeRear(root); 
       display(root); 
       break; 
      case 5: 
       display(root); 
       break; 
      default: 
       System.out.println("Invalid Option"); 
       break; 
      } 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
    System.out.println("Exited!!!"); 
    try { 
     reader.close(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    }  
} 

static Node insertNodeFront(int value, Node root){ 
    Node temp = new Node(value); 
    if(root==null){ 
     return temp; // as root or first 
    } 
    else 
    { 
     temp.next = root; 
     return temp; 
    }    
} 

static Node removeNodeFront(Node root){ 
    if(root==null){ 
     System.out.println("List is Empty"); 
     return null; 
    } 
    if(root.next==null){ 
     return null; // remove root itself 
    } 
    else 
    { 
     root=root.next;// make next node as root 
     return root; 
    }    
} 

static Node insertNodeRear(int value, Node root){ 
    Node temp = new Node(value); 
    Node cur = root; 
    if(root==null){ 
     return temp; // as root or first 
    } 
    else 
    { 
     while(cur.next!=null) 
     { 
      cur = cur.next; 
     } 
     cur.next = temp; 
     return root; 
    }    
} 

static Node removeNodeRear(Node root){ 
    if(root==null){ 
     System.out.println("List is Empty"); 
     return null; 
    } 
    Node cur = root; 
    Node prev = null; 
    if(root.next==null){ 
     return null; // remove root itself 
    } 
    else 
    { 
     while(cur.next!=null) 
     { 
      prev = cur; 
      cur = cur.next; 
     } 
     prev.next=null;// remove last node 
     return root; 
    }    
} 

static void display(Node root){ 
    System.out.println("Current List:"); 
    if(root==null){ 
     System.out.println("List is Empty"); 
     return; 
    } 
    while (root!=null){ 
     System.out.print(root.val+"->"); 
     root=root.next; 
    } 
    System.out.println(); 
} 

static class Node{ 
    int val; 
    Node next; 
    public Node(int value) { 
     // TODO Auto-generated constructor stub 
     val = value; 
     next = null; 
    } 
} 
} 
1

鏈表方案與以下功能

1 Insert At Start 
2 Insert At End 
3 Insert At any Position 
4 Delete At any Position 
5 Display 
6 Get Size 
7 Empty Status 
8 Replace data at given postion 
9 Search Element by position 
10 Delete a Node by Given Data 
11 Search Element Iteratively 
12 Search Element Recursively 




package com.elegant.ds.linkedlist.practice; 

import java.util.Scanner; 

class Node { 

    Node link = null; 
    int data = 0; 

    public Node() { 
     link = null; 
     data = 0; 
    } 

    public Node(int data, Node link) { 
     this.data = data; 
     this.link = null; 
    } 

    public Node getLink() { 
     return link; 
    } 

    public void setLink(Node link) { 
     this.link = link; 
    } 

    public int getData() { 
     return data; 
    } 

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

} 

class SinglyLinkedListImpl { 

    Node start = null; 
    Node end = null; 
    int size = 0; 

    public SinglyLinkedListImpl() { 
     start = null; 
     end = null; 
     size = 0; 
    } 

    public void insertAtStart(int data) { 
     Node nptr = new Node(data, null); 
     if (start == null) { 
      start = nptr; 
      end = start; 
     } else { 
      nptr.setLink(start); 
      start = nptr; 
     } 
     size++; 
    } 

    public void insertAtEnd(int data) { 
     Node nptr = new Node(data, null); 
     if (start == null) { 
      start = nptr; 
      end = nptr; 
     } else { 
      end.setLink(nptr); 
      end = nptr; 
     } 
     size++; 
    } 

    public void insertAtPosition(int position, int data) { 
     Node nptr = new Node(data, null); 
     Node ptr = start; 
     position = position - 1; 
     for (int i = 1; i < size; i++) { 
      if (i == position) { 
       Node temp = ptr.getLink(); 
       ptr.setLink(nptr); 
       nptr.setLink(temp); 
       break; 
      } 
      ptr = ptr.getLink(); 
     } 
     size++; 
    } 

    public void repleaceDataAtPosition(int position, int data) { 
     if (start == null) { 
      System.out.println("Empty!"); 
      return; 
     } 

     Node ptr = start; 
     for (int i = 1; i < size; i++) { 
      if (i == position) { 
       ptr.setData(data); 
      } 
      ptr = ptr.getLink(); 
     } 
    } 

    public void deleteAtPosition(int position) { 
     if (start == null) { 
      System.out.println("Empty!"); 
      return; 
     } 

     if (position == size) { 
      Node startPtr = start; 
      Node endPtr = start; 
      while (startPtr != null) { 
       endPtr = startPtr; 
       startPtr = startPtr.getLink(); 
      } 
      end = endPtr; 
      end.setLink(null); 
      size--; 
      return; 
     } 

     Node ptr = start; 
     position = position - 1; 
     for (int i = 1; i < size; i++) { 

      if (i == position) { 
       Node temp = ptr.getLink(); 
       temp = temp.getLink(); 
       ptr.setLink(temp); 
       break; 
      } 
      ptr = ptr.getLink(); 
     } 
     size--; 
    } 

    public void deleteNodeByGivenData(int data) { 
     if (start == null) { 
      System.out.println("Empty!"); 
      return; 
     } 

     if (start.getData() == data && start.getLink() == null) { 
      start = null; 
      end = null; 
      size--; 
      return; 
     } 

     if (start.getData() == data && start.getLink() != null) { 
      start = start.getLink(); 
      size--; 
      return; 
     } 

     if (end.getData() == data) { 
      Node startPtr = start; 
      Node endPtr = start; 

      startPtr = startPtr.getLink(); 
      while (startPtr.getLink() != null) { 
       endPtr = startPtr; 
       startPtr = startPtr.getLink(); 
      } 
      end = endPtr; 
      end.setLink(null); 
      size--; 
      return; 
     } 

     Node startPtr = start; 
     Node prevLink = startPtr; 
     startPtr = startPtr.getLink(); 
     while (startPtr.getData() != data && startPtr.getLink() != null) { 
      prevLink = startPtr; 
      startPtr = startPtr.getLink(); 
     } 
     if (startPtr.getData() == data) { 
      Node temp = prevLink.getLink(); 
      temp = temp.getLink(); 
      prevLink.setLink(temp); 
      size--; 
      return; 
     } 

     System.out.println(data + " not found!"); 
    } 

    public void disply() { 
     if (start == null) { 
      System.out.println("Empty!"); 
      return; 
     } 

     if (start.getLink() == null) { 
      System.out.println(start.getData()); 
      return; 
     } 

     Node ptr = start; 
     System.out.print(ptr.getData() + "->"); 
     ptr = start.getLink(); 
     while (ptr.getLink() != null) { 
      System.out.print(ptr.getData() + "->"); 
      ptr = ptr.getLink(); 
     } 
     System.out.println(ptr.getData() + "\n"); 
    } 

    public void searchElementByPosition(int position) { 
     if (position == 1) { 
      System.out.println("Element at " + position + " is : " + start.getData()); 
      return; 
     } 

     if (position == size) { 
      System.out.println("Element at " + position + " is : " + end.getData()); 
      return; 
     } 

     Node ptr = start; 
     for (int i = 1; i < size; i++) { 
      if (i == position) { 
       System.out.println("Element at " + position + " is : " + ptr.getData()); 
       break; 
      } 
      ptr = ptr.getLink(); 
     } 
    } 

    public void searchElementIteratively(int data) { 

     if (isEmpty()) { 
      System.out.println("Empty!"); 
      return; 
     } 

     if (start.getData() == data) { 
      System.out.println(data + " found at " + 1 + " position"); 
      return; 
     } 

     if (start.getLink() != null && end.getData() == data) { 
      System.out.println(data + " found at " + size + " position"); 
      return; 
     } 

     Node startPtr = start; 
     int position = 0; 
     while (startPtr.getLink() != null) { 
      ++position; 
      if (startPtr.getData() == data) { 
       break; 
      } 
      startPtr = startPtr.getLink(); 
     } 
     if (startPtr.getData() == data) { 
      System.out.println(data + " found at " + position); 
      return; 
     } 

     System.out.println(data + " No found!"); 
    } 

    public void searchElementRecursively(Node start, int data, int count) { 

     if (isEmpty()) { 
      System.out.println("Empty!"); 
      return; 
     } 
     if (start.getData() == data) { 
      System.out.println(data + " found at " + (++count)); 
      return; 
     } 
     if (start.getLink() == null) { 
      System.out.println(data + " not found!"); 
      return; 
     } 
     searchElementRecursively(start.getLink(), data, ++count); 
    } 

    public int getSize() { 
     return size; 
    } 

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

public class SinglyLinkedList { 

    @SuppressWarnings("resource") 
    public static void main(String[] args) { 
     SinglyLinkedListImpl listImpl = new SinglyLinkedListImpl(); 
     System.out.println("Singly Linked list : "); 
     boolean yes = true; 
     do { 
      System.out.println("1 Insert At Start :"); 
      System.out.println("2 Insert At End :"); 
      System.out.println("3 Insert At any Position :"); 
      System.out.println("4 Delete At any Position :"); 
      System.out.println("5 Display :"); 
      System.out.println("6 Get Size"); 
      System.out.println("7 Empty Status"); 
      System.out.println("8 Replace data at given postion"); 
      System.out.println("9 Search Element by position "); 
      System.out.println("10 Delete a Node by Given Data"); 
      System.out.println("11 Search Element Iteratively"); 
      System.out.println("12 Search Element Recursively"); 
      System.out.println("13 Exit :"); 
      Scanner scanner = new Scanner(System.in); 
      int choice = scanner.nextInt(); 
      switch (choice) { 
      case 1: 
       listImpl.insertAtStart(scanner.nextInt()); 
       break; 

      case 2: 
       listImpl.insertAtEnd(scanner.nextInt()); 
       break; 

      case 3: 
       int position = scanner.nextInt(); 
       if (position <= 1 || position > listImpl.getSize()) { 
        System.out.println("invalid position!"); 
       } else { 
        listImpl.insertAtPosition(position, scanner.nextInt()); 
       } 
       break; 

      case 4: 
       int deletePosition = scanner.nextInt(); 
       if (deletePosition <= 1 || deletePosition > listImpl.getSize()) { 
        System.out.println("invalid position!"); 
       } else { 
        listImpl.deleteAtPosition(deletePosition); 
       } 
       break; 

      case 5: 
       listImpl.disply(); 
       break; 

      case 6: 
       System.out.println(listImpl.getSize()); 
       break; 

      case 7: 
       System.out.println(listImpl.isEmpty()); 
       break; 

      case 8: 
       int replacePosition = scanner.nextInt(); 
       if (replacePosition < 1 || replacePosition > listImpl.getSize()) { 
        System.out.println("Invalid position!"); 
       } else { 
        listImpl.repleaceDataAtPosition(replacePosition, scanner.nextInt()); 
       } 
       break; 

      case 9: 
       int searchPosition = scanner.nextInt(); 
       if (searchPosition < 1 || searchPosition > listImpl.getSize()) { 
        System.out.println("Invalid position!"); 
       } else { 
        listImpl.searchElementByPosition(searchPosition); 
       } 
       break; 

      case 10: 
       listImpl.deleteNodeByGivenData(scanner.nextInt()); 
       break; 

      case 11: 
       listImpl.searchElementIteratively(scanner.nextInt()); 
       break; 

      case 12: 
       listImpl.searchElementRecursively(listImpl.start, scanner.nextInt(), 0); 
       break; 

      default: 
       System.out.println("invalid choice"); 
       break; 
      } 
     } while (yes); 
    } 
} 

這將幫助你在鏈表。

+0

它是一個非常好的實現,但我認爲在節點類的參數化構造函數中,應該設置'this.link = link;' – kiiiiNNNNNNNNNyyyy 2018-03-04 04:37:12