如何删除双链接列表中的尾部



我的老师在这个活动中指导我们如何删除双链接列表的尾部。他创建了一个循序渐进的过程或算法供我们遵循。我照做了,但没用。或者我可能是看错了。这是算法

检查列表是否为空

  • 如果不是空的
    • 检查列表中是否只有一个节点
      • 如果只有一个节点,则将头和尾引用设置为null
      • 如果有多个节点
        • 创建一个临时尾部以指向下一个尾部(tail.prev(
        • 将尾部的prev和temptail的next设置为null
        • 将temptail值指定给尾部

这是我的代码

public void delTail(){
DoubleNode temp;

if(isEmpty()){
return;
}
else if(!isEmpty()){
if(head == tail){
head = tail = null;
}
else{
temp = tail.next;
tail.prev = null;
temp.next = null;
temp = tail;
}
}

}

这是我在我的终端中看到的错误

我认为我遵循的是对的还是错的?非常感谢您的帮助:(

这是我的构造函数*

public class DoubleNode{
public DoubleNode prev;
public int data;
public DoubleNode next;
public DoubleNode(int d){
this(null, d, null);
}
public DoubleNode(DoubleNode p, int d, DoubleNode n){
prev = p;
data = d;
next = n;
}
}

这是mt整个操作员代码*

public class operator{
DoubleNode head;
DoubleNode tail;
DoubleNode laman;
String output = "";
public operator(){
head = tail = null;
}
public boolean isEmpty(){
return head == null;
}
public void addHead(int i){

if(isEmpty()){
head = tail =new DoubleNode(i);
}
else{
head = new DoubleNode(null, i, head);
head.prev = head;
}
}
public void addTail(int i){
DoubleNode last = new DoubleNode(i);  
if(isEmpty()){
head = tail = new DoubleNode(i);
}
else{
tail.next = last;
tail = last;
}
}
public void delHead(){
DoubleNode temp = head.next; 
if(head==tail){ //this if condition is testing if the head and tail is one only, 
head = tail =null;  //if there is only one this will set the tail and head to null
}
else{
head = head.next;
head = temp;
}
}
public void delTail(){
DoubleNode temp;
if(isEmpty()) {  
return;  
}  
else {  
if(head != tail) {   
tail = tail.prev;
temp = tail;

}

else {  
head = tail = null;  
}  
}  
}
public void display(){
DoubleNode tmp = head;
output = "<html>";

for(tmp = head; tmp != null; tmp = tmp.next){
output = output + "<br>" + tmp.data + "<b>" + "<br>";

}
output = output + "</html>";
}
}

到目前为止,这是我的全部代码,我有一个带有jframe的主类,但我认为这很好,因为我也将其用于单个链接列表。但我在双链接列表中确实有一个关于删除最后一个节点的问题

您的问题是,您只是分配给temp,但实际上并没有使用它。此外,您没有正确设置回上一个元素的链接。

假设tail.next再次指向head,则可以执行以下操作:

tail.prev.next = tail.next; //you might need to check for `tail.prev` being null 
tail.next.prev = tail.prev; //you might need to check for `tail.next` being null
//delete tail

举例说明:

A -next-> Tail -next-> Head
^---prev--+  ^---prev--+

步骤1:

+----next--------------V
A         Tail -next-> Head
^---prev--+  ^---prev--+

步骤2:

+----next--------------V
A         Tail -next-> Head
^---prev--+            |
^--------------prev----+

实际上,如果tail.next == head移除尾部与移除任何其他节点没有什么不同。

您的else块中有两个错误:

  • 您永远不会更改tail引用。最后一条语句实际上应该是对tail的赋值。

  • 您似乎认为tail有一个非空的next引用,但这是矛盾的。尾部应该是最后一个节点,因此其next引用将始终为null(除非您应该创建循环列表(。因此,temp将为null,而语句temp.next = tail将触发null指针异常。

    tail更有趣的属性是它的prev属性,它指的是在当前尾部节点被移除后将成为tail的节点。你的作业中明确提到了这个tail.prev

所以:

else {
temp = tail.prev; // <--- should point to the new tail
tail.prev = null;
temp.next = tail;
tail = temp;  // <--- reverse the assignment
}

其他几个问题

addHead中,您没有正确设置prev属性。你把它作为一个自我参考。请注意,head已经在引用新节点。更改:

head.prev = head;

至:

head.next.prev = head;

addTail中,缺少对prev的分配。更改:

tail.next = last;
tail = last;

至:

tail.next = last;
last.prev = tail; // needed!
tail = last;

delHead中,必须确保新头的prev为空。所以改变:

head = temp;

至:

head = head.next;
head.prev = null;

注意:那个方法不需要DoubleNode temp = head.next;

最新更新