2010-11-01 79 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