Java 在单链表中添加和删除

Java 在单链表中添加和删除,java,linked-list,singly-linked-list,Java,Linked List,Singly Linked List,我以为我在上一个关于链表的问题中已经理解了这一点,但我大错特错了,我和最初发布时一样迷失了方向 我意识到,从技术上讲,我在问两个问题,但希望至少有一个问题会让另一个问题变得容易(假设它们正好相反) 我已经上了3节课,它们是: SLinkedList.java package chapter3.linkedList; public class SLinkedList<V> { // instance variables. Add the tail refer

我以为我在上一个关于链表的问题中已经理解了这一点,但我大错特错了,我和最初发布时一样迷失了方向

我意识到,从技术上讲,我在问两个问题,但希望至少有一个问题会让另一个问题变得容易(假设它们正好相反)

我已经上了3节课,它们是:

SLinkedList.java

package chapter3.linkedList;

    public class SLinkedList<V> {
        // instance variables.  Add the tail reference.
        protected Node<V> head, tail;
        protected long size;

        // methods, empty list constructor first
        public SLinkedList () {
            head = null;
            tail = null;
            size = 0;
        }  // end constructor of a SLinkedList

        // method to add nodes to the list.  Storage space for the node
        // is already allocated in the calling method
        public void addFirst (Node<V> node) {
            // set the tail only if this is the very first node
            if (tail == null)
                tail = node;
            node.setNext (head);    // make next of the new node refer to the head
            head = node;            // give head a new value

            // change our size
            size++;
        }  // end method addFirst

        // addAfter - add new node after current node, checking to see if we are at the tail
        public void addAfter (Node<V>currentNode, Node<V>newNode) {
            if (currentNode == tail)
                tail = newNode;
            newNode.setNext (currentNode.getNext ());
            currentNode.setNext (newNode);

            // change our size
            size++;
        }  // end method addAfter

        // addLast - add new node after the tail node.  Adapted from Code Fragment 3.15, p. 118.
        // Mike Qualls
        public void addLast (Node<V> node) {
            node.setNext (null);
            tail.setNext (node);
            tail = node;
            size++;     
        }  // end method addLast

        // methods to remove nodes from the list.  (Unfortunately, with a single linked list
        // there is no way to remove last.  Need a previous reference to do that.  (See
        // Double Linked Lists and the code below.)
        public Node<V> removeFirst () {
            if (head == null)
                System.err.println("Error:  Attempt to remove from an empty list");

            // save the one to return
            Node<V> temp = head;

            // do reference manipulation
            head = head.getNext ();
            temp.setNext(null);
            size--;

            return temp;

        }  // end method removeFirst

        // remove the node at the end of the list.  tail refers to this node, but
        // since the list is single linked, there is no way to refer to the node
        // before the tail node.  Need to traverse the list.
        public Node<V> removeLast () {
            // // declare local variables/objects
            Node<V> nodeBefore;
            Node<V> nodeToRemove;

            // make sure we have something to remove
            if (size == 0)
                System.err.println("Error:  Attempt to remove fron an empty list");

            // traverse through the list, getting a reference to the node before
            // the trailer.  Since there is no previous reference.
            nodeBefore = getFirst ();

            // potential error  ??  See an analysis and drawing that indicates the number of iterations
            // 9/21/10.  size - 2 to account for the head and tail nodes.  We want to refer to the one before the
            // tail.
            for (int count = 0; count < size - 2; count++)
                nodeBefore = nodeBefore.getNext ();

            // save the last node
            nodeToRemove = tail;

            // now, do the pointer manipulation
            nodeBefore.setNext (null);
            tail = nodeBefore;
            size--;

            return nodeToRemove;

        }  // end method removeLast

        // method remove.  Remove a known node from the list.  No need to search or return a value.  This method
        // makes use of a 'before' reference in order to allow list manipulation.
        public void remove (Node<V> nodeToRemove) {
            // declare local variables/references
            Node<V> nodeBefore, currentNode;

            // make sure we have something to remove
            if (size == 0)
                System.err.println("Error:  Attempt to remove fron an empty list");

            // starting at the beginning check for removal
            currentNode = getFirst ();
            if (currentNode == nodeToRemove)
                removeFirst ();
            currentNode = getLast ();
            if (currentNode == nodeToRemove)
                removeLast ();

            // we've already check two nodes, check the rest
            if (size - 2 > 0) {
                nodeBefore = getFirst ();
                currentNode = getFirst ().getNext ();
                for (int count = 0; count < size - 2; count++) {
                    if (currentNode == nodeToRemove) {
                        // remove current node
                        nodeBefore.setNext (currentNode.getNext ());
                        size--;
                        break;
                    }  // end if node found

                    // change references
                    nodeBefore = currentNode;
                    currentNode = currentNode.getNext ();
                }  // end loop to process elements
            }  // end if size - 2 > 0

        }  // end method remove

        // the gets to return the head and/or tail nodes and size of the list
        public Node<V> getFirst () { return head; }
        public Node<V> getLast () { return tail; }  
        public long getSize () { return size; }

    }  // end class SLinkedList
编辑点 我创建了一个名为Scores.java的驱动程序,到目前为止,我所拥有的只是**我已经添加了我认为需要的类,但我可能错了:

package Project_1;

import chapter3.linkedList.*;

import java.util.*;


/** Class for storing high scores in an array in non-decreasing order. */
public class Scores 
{

    //add function
    public SLinkedList<GameEntry> add(GameEntry rank, SLinkedList<GameEntry> scores)
    {
        Node<GameEntry> currentNode = scores.getFirst();
        Node<GameEntry> nextNode = null;
        Node<GameEntry> previousNode = null;
        Node<GameEntry> newNode = new Node<GameEntry>();
        newNode.setElement(rank);

        if(scores.getSize() == 0)
        {
            scores.addFirst(newNode);
        }
        else
        {
            while(currentNode != null)
            {               
                nextNode = currentNode.getNext();
                if(nextNode == null)
                {
                    scores.addLast(newNode);
                }
                else
                {
                    scores.addAfter(currentNode, newNode);
                    break;
                }               
            previousNode = currentNode;
            currentNode = currentNode.getNext();
            }
        }
        return scores;
    }

    //remove function
    public void remove(int i)
    {

    }

    //print function
    /*gameenter printing; 
printing=node.Getelement;           //pseudo code for making it work right
print(printing.getscore) 
print(print.getname) 
*/
    public void print(SLinkedList<GameEntry> scores)
    {
        Node<GameEntry> currentNode = scores.getFirst();        
        GameEntry currentEntry = currentNode.getElement();      
        System.out.printf("[");
        for(int i = 0; i < scores.getSize(); i++)
        {
                System.out.printf(", %s", currentEntry.toString());
                currentNode = currentNode.getNext();
                currentEntry = currentNode.getElement();
        }
        System.out.println("]");
    }
}
package项目_1;
导入第3章链接列表。*;
导入java.util.*;
/**类,用于以非递减顺序在数组中存储高分*/
公开课成绩
{
//添加函数
公共链接列表添加(游戏条目排名、链接列表分数)
{
节点currentNode=scores.getFirst();
节点nextNode=null;
节点previousNode=null;
Node newNode=新节点();
setElement(秩);
if(scores.getSize()==0)
{
scores.addFirst(newNode);
}
其他的
{
while(currentNode!=null)
{               
nextNode=currentNode.getNext();
if(nextNode==null)
{
scores.addLast(newNode);
}
其他的
{
scores.addAfter(currentNode,newNode);
打破
}               
previousNode=currentNode;
currentNode=currentNode.getNext();
}
}
返回分数;
}
//删除函数
删除公共空间(int i)
{
}
//打印功能
/*游戏中心打印;
printing=node.Getelement;//使其正常工作的伪代码
打印(打印.getscore)
打印(print.getname)
*/
公开作废打印(SLinkedList分数)
{
节点currentNode=scores.getFirst();
GameEntry currentEntry=currentNode.getElement();
System.out.printf(“[”);
对于(int i=0;i
我有一个名为ScoresTest.java的测试驱动程序,我已经填写了很多:

一揽子计划1

导入第3章linkedList.SLinkedList

 public class ScoresTest {
    /**
     * @param args
     */

    public static void main(String[] args) 
    {
        SLinkedList<GameEntry> highScores = new SLinkedList<GameEntry>();  //Linked List for Game Entry
        GameEntry entry;
        Scores rank = new Scores();     
        entry = new GameEntry("Flanders", 681);     
        highScores = rank.add(entry, highScores);
        entry = new GameEntry("Krusty", 324);
        highScores = rank.add(entry, highScores); 
        entry = new GameEntry("Otto", 438);
        highScores = rank.add(entry, highScores); 
        entry = new GameEntry("Bart", 875);
        highScores = rank.add(entry, highScores); 
        entry = new GameEntry("Homer", 12);
        highScores = rank.add(entry, highScores); 
        entry = new GameEntry("Lisa", 506);
        highScores = rank.add(entry, highScores); 
        entry = new GameEntry("Maggie", 980);
        highScores = rank.add(entry, highScores); 
        entry = new GameEntry("Apoo", 648);
        highScores = rank.add(entry, highScores); 
        entry = new GameEntry("Smithers", 150);
        highScores = rank.add(entry, highScores); 
        entry = new GameEntry("Burns", 152);
        highScores = rank.add(entry, highScores); 
        System.out.println("The Original High Scores");
        rank.print(highScores);

        entry = new GameEntry("Moe", 895);
        highScores = rank.add(entry, highScores);
        System.out.println("Scores after adding Moe");
        rank.print(highScores);

        //highScores = rank.remove(4);
        System.out.println("Scores after removing Apoo");
        rank.print(highScores);
    }
}
public class ScoresTest{
/**
*@param args
*/
公共静态void main(字符串[]args)
{
SLinkedList highScores=新建SLinkedList();//游戏条目的链接列表
游戏入口;
分数等级=新分数();
入口=新游戏入口(“法兰德斯”,681);
highScores=排名。添加(条目,highScores);
条目=新游戏条目(“Krusty”,324);
highScores=排名。添加(条目,highScores);
条目=新游戏条目(“奥托”,438);
highScores=排名。添加(条目,highScores);
入口=新游戏入口(“Bart”,875);
highScores=排名。添加(条目,highScores);
条目=新游戏条目(“荷马”,12);
highScores=排名。添加(条目,highScores);
条目=新游戏条目(“Lisa”,506);
highScores=排名。添加(条目,highScores);
条目=新游戏条目(“玛吉”,980);
highScores=排名。添加(条目,highScores);
条目=新游戏条目(“Apoo”,648);
highScores=排名。添加(条目,highScores);
条目=新游戏条目(“史密斯”,150);
highScores=排名。添加(条目,highScores);
条目=新游戏条目(“Burns”,152);
highScores=排名。添加(条目,highScores);
System.out.println(“原始高分”);
排名。打印(高分);
条目=新游戏条目(“Moe”,895);
highScores=排名。添加(条目,highScores);
System.out.println(“添加Moe后的分数”);
排名。打印(高分);
//高分=排名。删除(4);
System.out.println(“删除Apoo后的分数”);
排名。打印(高分);
}
}
已经全部结束了,我肯定没有什么要补充的了

我不想找人帮我回答这个问题,但我不知道从哪里开始,也不知道如何以任何方式实现添加或删除功能。这是一门中级课程,这本书对解释链表没有任何帮助(如果你不相信我,请自找吧,Java中的文本称为数据结构和算法,第5版)。它展示了如何很容易地使用数组来实现这一点……这对于链表来说非常有效,但显然老师不希望我们这样做,所以很遗憾,我现在完全不知道如何做到这一点

我试着在这里和谷歌上查看其他人的答案,到目前为止,没有任何东西点击或有任何意义,我只是无法理解它是如何工作的,老师的解释和示例只是在黑板上画框,我从来没有见过排序,加上,或者删除为链表编码的函数…不知道我没有学习过什么或找不到什么

非常感谢您的帮助,并提前向您表示感谢

编辑

我查看了导入java.util.*;其中的链表命令看起来非常简单。要删除,我只需使用list.sublist(I,I).clear();我想删除的值被删除了,非常简单,它似乎只是试图利用slinkedlist.java和node.java,我似乎无法以任何方式或形式遵循它们。我相信老师确实写了,我也试着请求他的帮助,下课后呆了两个小时试图从他那里得到任何理解,正如你所看到的,这一点帮助都不大。再次感谢您的帮助

编辑package Project_1; import chapter3.linkedList.*; import java.util.*; /** Class for storing high scores in an array in non-decreasing order. */ public class Scores { //add function public SLinkedList<GameEntry> add(GameEntry rank, SLinkedList<GameEntry> scores) { Node<GameEntry> currentNode = scores.getFirst(); Node<GameEntry> nextNode = null; Node<GameEntry> previousNode = null; Node<GameEntry> newNode = new Node<GameEntry>(); newNode.setElement(rank); if(scores.getSize() == 0) { scores.addFirst(newNode); } else { while(currentNode != null) { nextNode = currentNode.getNext(); if(nextNode == null) { scores.addLast(newNode); } else { scores.addAfter(currentNode, newNode); break; } previousNode = currentNode; currentNode = currentNode.getNext(); } } return scores; } //remove function public void remove(int i) { } //print function /*gameenter printing; printing=node.Getelement; //pseudo code for making it work right print(printing.getscore) print(print.getname) */ public void print(SLinkedList<GameEntry> scores) { Node<GameEntry> currentNode = scores.getFirst(); GameEntry currentEntry = currentNode.getElement(); System.out.printf("["); for(int i = 0; i < scores.getSize(); i++) { System.out.printf(", %s", currentEntry.toString()); currentNode = currentNode.getNext(); currentEntry = currentNode.getElement(); } System.out.println("]"); } }
 public class ScoresTest {
    /**
     * @param args
     */

    public static void main(String[] args) 
    {
        SLinkedList<GameEntry> highScores = new SLinkedList<GameEntry>();  //Linked List for Game Entry
        GameEntry entry;
        Scores rank = new Scores();     
        entry = new GameEntry("Flanders", 681);     
        highScores = rank.add(entry, highScores);
        entry = new GameEntry("Krusty", 324);
        highScores = rank.add(entry, highScores); 
        entry = new GameEntry("Otto", 438);
        highScores = rank.add(entry, highScores); 
        entry = new GameEntry("Bart", 875);
        highScores = rank.add(entry, highScores); 
        entry = new GameEntry("Homer", 12);
        highScores = rank.add(entry, highScores); 
        entry = new GameEntry("Lisa", 506);
        highScores = rank.add(entry, highScores); 
        entry = new GameEntry("Maggie", 980);
        highScores = rank.add(entry, highScores); 
        entry = new GameEntry("Apoo", 648);
        highScores = rank.add(entry, highScores); 
        entry = new GameEntry("Smithers", 150);
        highScores = rank.add(entry, highScores); 
        entry = new GameEntry("Burns", 152);
        highScores = rank.add(entry, highScores); 
        System.out.println("The Original High Scores");
        rank.print(highScores);

        entry = new GameEntry("Moe", 895);
        highScores = rank.add(entry, highScores);
        System.out.println("Scores after adding Moe");
        rank.print(highScores);

        //highScores = rank.remove(4);
        System.out.println("Scores after removing Apoo");
        rank.print(highScores);
    }
}
newNode->nextNode = startNode
startNode = newNode
index = 0
currentNode = startNode

// find the node in the list. here you will need to do all kinds of bound checking
while index is less than position
    currentNode = currentNode.nextNode  // move your node pointer to the position
    increment index

// so here we basically insert the new node into the list. what needs to happen is
// to NOT break the list by forgetting the node after the current node. this is why
// we first set the new nodes' next one, to the current nodes' (the one already in
// the list) next node. this way, we still have all the information we need. then,
// when we set the current nodes' next node to the new node, we essentially "break"
// the link and "repair" it by adding the new link.

newNode.nextNode = currentNode.nextNode // some more bound checking required
currentNode.nextNode = newNode
index = 0
delNode = startNode

// find the node in the list. here you will need to do all kinds of bound checking
while index is less than (position - 1)
    delNode = delNode.nextNode  // move your node pointer to the position
    increment index

delNode.nextNode = delNode.nextNode.nextNode

// that's it. by setting the node's (before the one you whish to delete)
// next node to the node AFTER the one you want to delete, you basically
// "skip" over that node. since it is no longer referenced, the garbage
// collector will take care of the rest. if you wish to return that node
// you can do it quite easily by remembering it.

storeNode = delNode.nextNode                 // some more bound checking required
delNode.nextNode = delNode.nextNode.nextNode // some more bound checking required

// now you still have a reference to the deleted node in storeNode
//add function
public void add(Node<GameEntry> score) {
    // adding is where you now want to keep everything sorted. so I highly
    // recommend that you implement `Comparable` as I mentioned above. if not,
    // you have to put the logic in here.

    Node<GameEntry> currentNode = highScored.getFirst();
    Node<GameEntry> prevNode = null;

    // if the list is empty, or the new node must go in before the head,
    // simply add it as the head.
    if (highScores.size() == 0 || score.compareTo(currentNode) < 0) {
        highScores.addFirst(score);
    }

    // search for the position of the new node. while the node has a higher score
    // than the current node, we need to continue on so we can place it in the
    // correct place.
    while (currentNode != null && currentNode.compareTo(score) > 0) {
        prevNode = currentNode;
        currentNode = currentNode.getNext();
    }

    // if the currentNode is null, it means it is the highest score, so
    // we can simply add it to the end
    if (currentNode == null) {
        highScores.addLast(score);
    } else {
        // otherwise just add it after the correct node
        highScores.addAfter(prevNode, score);
    }
}


//remove function
public void remove(Node<GameEntry> score) {
    // removing an element should be as described above. if you keep
    // your list sorted during the ADD method, removing any element
    // should not break the order.

    // find the element - removal from a linked list is O(n),
    // since we need to know what the element BEFORE the one
    // is that you want to remove. assuming you have implemented
    // the equals method to check equality of nodes:

    Node<GameEntry> currentNode = highScores.getFirst();
    Node<GameEntry> prevNode = null;
    while (currentNode != null && !currentNode.equals(score)) {
        prevNode = currentNode;
        currentNode = currentNode.getNext();
    }

    // if currentNode is null, the node we wanted to remove was not
    // in the list.
    if (currentNode == null) {
        System.out.println("Node not found");
        return;
    }

    // now, we need to check if there is a node after the one we want
    // to remove.
    if (prevNode.getNext().getNext() != null) {
        // if there is, we follow the logic from the pseudo code
        prevNode.setNext(prev.getNext().getNext());
    } else {
        // if not, we only need to remove the last entry (since the
        // one we want to remove is the last one)
        highScores.removeLast();
    }
}