Java 对自定义linkedlist使用递归
作为家庭作业,我被告知写一个自定义链表的插入方法(按顺序)。我写了基本情况,但我仍然不理解递归情况。我知道我只是问如何编写contain方法,有人帮了我,但在这种情况下,我不必像这个方法那样对列表进行任何修改。请帮助我了解是什么导致我的链表被覆盖,以及是否有更简单的方法来简化我的代码 这是我的密码:Java 对自定义linkedlist使用递归,java,Java,作为家庭作业,我被告知写一个自定义链表的插入方法(按顺序)。我写了基本情况,但我仍然不理解递归情况。我知道我只是问如何编写contain方法,有人帮了我,但在这种情况下,我不必像这个方法那样对列表进行任何修改。请帮助我了解是什么导致我的链表被覆盖,以及是否有更简单的方法来简化我的代码 这是我的密码: public class OrderedList { private Node first; //Constructor public OrderedList() { this.firs
public class OrderedList {
private Node first;
//Constructor
public OrderedList() {
this.first = null;
}
//Return the number of items in the list
public int size() {
int counter = 0;
Node pointer = this.first;
while (pointer != null) {
counter++;
pointer = pointer.next;
}
return counter;
}
//Return an array of copies of the stored elements
public Comparable[] getStore() {
Comparable[] elements = new Comparable[size()];
Node pointer = this.first;
if (this.first == null) {
return elements;
} else {
int i = 0;
while (pointer != null) {
elements[i] = pointer.data;
pointer = pointer.next;
i++;
}
return elements;
}
}
//true iff item matches a stored element
//Recursive
public boolean contains(Comparable item) {
return containsHelper(this.first, item);
}
private boolean containsHelper(Node node, Comparable item) {
//base case
if (node == null) {
return false;
} else {
if (node.data.compareTo(item) == 0) {
return true;
}
return containsHelper(node.next, item);
}
}
//Add item preserving the order of the elements
//Recursive
public void insert(Comparable item) {
insertHelper(this.first, item);
}
public void insertHelper(Node pointer, Comparable item) {
//Base case
Node store = new Node(item);
if (pointer == null) {
store.next = this.first;
this.first = store;
return;
}
if (pointer.data.compareTo(item) > 0 ) {
store.next = pointer;
return;
}
if (pointer.data.compareTo(item) < 0 && pointer.next == null) {
store.next = pointer.next;
pointer.next = store;
return;
} else {
Node save = this.first;
this.first = this.first.next;
insertHelper(this.first, item);
if (pointer.data.compareTo(item) > 0) {
save.next = store;
this.first = save;
} else {
save.next = pointer;
this.first = save;
}
}
}
公共类OrderedList{
私有节点优先;
//建造师
公共订单列表(){
this.first=null;
}
//返回列表中的项目数
公共整数大小(){
int计数器=0;
节点指针=this.first;
while(指针!=null){
计数器++;
指针=pointer.next;
}
返回计数器;
}
//返回存储元素的副本数组
公共可比[]getStore(){
可比[]元素=新的可比[size()];
节点指针=this.first;
if(this.first==null){
返回元素;
}否则{
int i=0;
while(指针!=null){
元素[i]=指针.data;
指针=pointer.next;
i++;
}
返回元素;
}
}
//true iff项与存储的元素匹配
//递归的
公共布尔包含(可比项){
退回集装箱箱(本条第一项);
}
专用布尔容器容器(节点,可比项){
//基本情况
if(node==null){
返回false;
}否则{
if(node.data.compareTo(item)==0){
返回true;
}
返回containsHelper(node.next,item);
}
}
//添加保持元素顺序的项
//递归的
公共空白插入(可比项目){
insertHelper(第一项);
}
public void insertHelper(节点指针,可比较项){
//基本情况
节点存储=新节点(项目);
if(指针==null){
store.next=this.first;
这个。第一个=商店;
返回;
}
if(指针数据比较(项)>0){
store.next=指针;
返回;
}
if(pointer.data.compareTo(item)<0&&pointer.next==null){
store.next=pointer.next;
pointer.next=store;
返回;
}否则{
节点保存=this.first;
this.first=this.first.next;
insertHelper(第一项);
if(指针数据比较(项)>0){
save.next=store;
this.first=保存;
}否则{
save.next=指针;
this.first=保存;
}
}
}
我只给你答案的一部分。考虑这个线索。然后有更多的线索。看看你能在找到一个完整答案之前找到答案。
线索1
这部分代码不能在递归方法中,因为它引用了链表的头。您的递归是沿着列表向下移动,将其分为头和其余部分,决定是否在头插入,如果插入必须在其余部分,则递归
if (pointer == null) {
store.next = this.first;
this.first = store;
return;
}
应该稍微修改一下,这样它就可以进入处理整个列表的insert()
方法
为什么?
因为这段代码处理的是整个列表,并且会问这样一个问题,“这个列表是空的吗?”
线索2
现在,对于代码的这一部分:
if (pointer.data.compareTo(item) > 0 ) {
store.next = pointer;
return;
}
Node save = this.first;
this.first = this.first.next;
insertHelper(this.first, item);
if (pointer.data.compareTo(item) > 0) {
save.next = store;
this.first = save;
} else {
save.next = pointer;
this.first = save;
}
注意它是如何引用整个列表的。这是一件坏事
它会问这样一个问题:“新项目(要插入)是否应该放在当前主项目的前面?”
如果答案是“是”,则需要将其插入当前标题前,将当前标题与链接列表的当前其余部分保持不变,并返回一些内容,以便调用代码附加新排列的列表其余部分
if (pointer.data.compareTo(item) > 0 ) {
store.next = pointer; // new item goes in front of this part of list
return store;
}
线索3
现在,让我们跳到代码的这一部分:
if (pointer.data.compareTo(item) > 0 ) {
store.next = pointer;
return;
}
Node save = this.first;
this.first = this.first.next;
insertHelper(this.first, item);
if (pointer.data.compareTo(item) > 0) {
save.next = store;
this.first = save;
} else {
save.next = pointer;
this.first = save;
}
此代码没有问题。它只是递归,因为我们知道不需要对当前链接列表的标题进行任何更改。当我们递归时,我们将其传递到链接列表的其余部分,并告诉它如何修复。我们不在乎如何修复,因为我们相信它会通过在正确的位置插入新项来修复列表的其余部分
下面是我们要做的:
Node rest = insertHelper(pointer.next, item);
pointer.next = rest;
return pointer;
线索4
守则的这一部分是最后一个需要考虑的部分:
if (pointer.data.compareTo(item) < 0 && pointer.next == null) {
store.next = pointer.next;
pointer.next = store;
return;
}
我们所要做的就是返回新节点,它将是新的“列表的其余部分”,而不是列表的其余部分中没有任何内容
if (pointer.data.compareTo(item) > 0 ) {
store.next = pointer; // new item goes in front of this part of list
return store;
}
再来一个音符
请记住,方法签名必须更改为如下所示:
/**
* Insert the 'item' into the linked list beginning with the supplied node, 'pointer'
* @returns the new, modified linked list, with the new item in it.
*/
public Node insertHelper(Node pointer, Comparable item) {
if (this.next == null || this.data > item.data) { // pseudo code for greater than
item.next = this.next;
this.next = item;
return;
}
this.next.insert(item);
整件事
这包括对“插入”方法的更改:
public void insert(Comparable item) {
// if there isn't anything in the list, the new item becomes the whole list
if (first == null) {
Node store = new Node(item);
store.next = null;
this.first = store;
return;
}
// Otherwise let the helper fix up the list for us to store away
this.first = insertHelper(this.first, item);
}
public Node insertHelper(Node pointer, Comparable item) {
Node store = new Node(item);
if (pointer.data.compareTo(item) > 0 ) {
store.next = pointer; // new item goes in front of this part of list
return store;
}
if (pointer.next == null) {
return store; // new item becomes this part of the list
}
// The head of this part of the list is ok, fix the rest of the list
pointer.next = insertHelper(pointer.next, item);
return pointer;
}
进一步评论
还有另一种方法,将第一个节点存储在另一个类中,每个节点
只存储指向列表其余部分的指针(如下一步
)
然后,您有一个插入的方法,该方法知道在调用它时它不能为null,因为如果它为null,您就不能调用它
因此,在insert
中没有测试第一个值是否为null。但这意味着调用者必须执行以下操作:
Node item = new Node(data);
if (list != null) {
list.insert(item);
} else {
list = item;
}
插入方法如下所示:
/**
* Insert the 'item' into the linked list beginning with the supplied node, 'pointer'
* @returns the new, modified linked list, with the new item in it.
*/
public Node insertHelper(Node pointer, Comparable item) {
if (this.next == null || this.data > item.data) { // pseudo code for greater than
item.next = this.next;
this.next = item;
return;
}
this.next.insert(item);
就是这样。你能澄清确切的问题是什么吗?确切的问题是我的insert方法的递归部分。@M0SKIT0这不够准确。它做错了什么?你应该澄清你是如何知道问题所在的。错误的输出?你期望作为输出的是什么?你提供了什么数据?两条无疑问的注释。1.你的contains方法没有利用这是一个有序列表的事实,而是遍历整个列表,而不是在遇到更大的值时停止。2.与递归相比,使用迭代编写这些方法显然更容易。递归是强制的吗?但是