Java 在单链表中添加和删除
我以为我在上一个关于链表的问题中已经理解了这一点,但我大错特错了,我和最初发布时一样迷失了方向 我意识到,从技术上讲,我在问两个问题,但希望至少有一个问题会让另一个问题变得容易(假设它们正好相反) 我已经上了3节课,它们是: SLinkedList.javaJava 在单链表中添加和删除,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
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();
}
}