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

Java 如何删除双链接列表中的尾部?,java,constructor,linked-list,double,tail,Java,Constructor,Linked List,Double,Tail,我的老师指导我们如何删除双链接列表的尾部。他为我们创建了一个循序渐进的过程或算法。我遵循了它,但它不起作用。或者也许我看错了。这是算法 检查列表是否为空 如果不是空的 检查列表中是否只有一个节点 如果只有一个节点,请将head和tail引用设置为null 如果有多个节点 创建一个指向下一个尾部的试探性邮件(tail.prev) 将尾部的上一个和下一个设置为null 将TENTAIL值指定给尾部 这是我的代码 public void delTail(){ Do

我的老师指导我们如何删除双链接列表的尾部。他为我们创建了一个循序渐进的过程或算法。我遵循了它,但它不起作用。或者也许我看错了。这是算法

检查列表是否为空

  • 如果不是空的
    • 检查列表中是否只有一个节点
      • 如果只有一个节点,请将head和tail引用设置为null
      • 如果有多个节点
        • 创建一个指向下一个尾部的试探性邮件(tail.prev)
        • 将尾部的上一个和下一个设置为null
        • 将TENTAIL值指定给尾部
这是我的代码

    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;
}
}
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>";
}
}
这是mt整个操作员代码*

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;
}
}
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>";
}
}
公共类运算符{
双结点头;
双节尾;
双节点拉曼;
字符串输出=”;
公共运营商(){
头=尾=空;
}
公共布尔值为空(){
返回头==null;
}
公共无效地址(int i){
if(isEmpty()){
头部=尾部=新的双节点(i);
}
否则{
head=新的双节点(null,i,head);
head.prev=头;
}
}
公共无效地址(int i){
DoubleNode last=新的DoubleNode(i);
if(isEmpty()){
头部=尾部=新的双节点(i);
}
否则{
tail.next=last;
尾=最后一个;
}
}
公海{
DoubleNode温度=head.next;
if(head==tail){//如果head和tail仅为一,则此if条件正在测试,
head=tail=null;//如果只有一个,则会将tail和head设置为null
}
否则{
head=head.next;
压头=温度;
}
}
公共无效delTail(){
双节点温度;
如果(isEmpty()){
返回;
}  
否则{
如果(头!=尾){
tail=tail.prev;
温度=尾部;
}
否则{
头=尾=空;
}  
}  
}
公共空间显示(){
双节点tmp=头部;
输出=”;
for(tmp=head;tmp!=null;tmp=tmp.next){
输出=输出+“
”+tmp.data++“
”; } 输出=输出+“”; } }

这是我到目前为止的全部代码,我有一个带有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
    有一个非空的
    next
    引用,但这是一个矛盾。尾部应该是最后一个节点,因此其
    next
    引用将始终为空(除非您应该创建循环列表)。因此,
    temp
    将为null,语句
    temp.next=tail
    将触发null指针异常

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

因此:

else{

temp=tail.prev;//I您的代码以什么方式不起作用?您看到了什么错误或问题?代码段与DLL tail中的伪代码不匹配。next始终为null(请记住tail在末尾,因此没有next)。删除尾部时,
tail.prev
实际上指向您现在想要的尾部。因此,
tail=tail.prev;tail.next=null;
似乎是您所需要的一切。
temp
永远不会被使用-除非您想保存旧的
tail
,以便您可以清除它的“prev”以帮助垃圾收集。确实如此我的if-else条件有效吗?这就是问题所在吗?我尝试了我在这里提出的所有建议,但都不起作用。请注意,您添加的代码中还有许多其他错误:1)您有双重赋值,如
head=head.next;head=temp;
2)您并不总是维护
prev
next
correc注意,当删除
节点时,需要将
节点.prev.next
指向
节点.next
节点.next.prev
指向
节点.prev
。当插入
节点时,还需要调整引用:
节点.next=after.next;节点.prev=after;节点.next.prev=after;节点.next.prev=node;
之后的
将是您插入之后的节点)。你还需要考虑当你只有一个节点时你会做什么:是否应该
head==tail
为真?是否应该
head.next==head
head.prev==head
为真?如果不是,那么你需要处理那个特殊情况。我试着按照你的指示去做?但是你能检查我上面的If和else条件吗?是太多还是太多是否需要我的代码?@Bianxzy这取决于你是否真的希望
头和
尾相互指向。如果是这样,你基本上只需要以下检查:
头==null
(在这种情况下
tai
tail.next = last;
tail = last;
tail.next = last;
last.prev = tail; // needed!
tail = last;
head = temp;
head = head.next;
head.prev = null;