费了将近一天时间,终于实现了一个双向链表,支持正向和逆向的输出;
当实现逆向输出时有一问题一直困扰着我,就是删除某个指定元素后,正向输出显示已删除该元素,逆向输出显示没有删除该元素,百思不得姐啊,也知道问题出在deleteKey(long dd)方法中,但是具体位置找不到,后来逐步试验,略得蛛丝马迹,发现删除表头元素和表尾元素后正向输出和逆向输出是一致的,而删除其他地方元素两者输出不一致,最后将问题锁定在“当前指针指在一般位置时的代码处”,恩!问题果然在这里,写引用时少写了一个,逻辑上出了问题,导致没能正常删掉当前数据项,下面就剖析一下我的错误!
没有执行删除代码前,对于双向链表来说一般位置上的数据项(非表头和表尾)前后的引用形式如下图所示:
执行完我最初写的代码后,代码如下,引用变成如下形式:
current.previous.next = current.next;
current.next = current.previous;
执行完代码后:
所以才会出现正向输出时显示删除了该数据项,逆向输出时没有删除该数据项。
经分析,是引用的形式写错了,代码应该写成如下形式:
current.previous.next = current.next;
current.next.previous = current.previous;
执行完毕,该数据项被删除了,变成一座孤岛,没有人与他连接,被“孤立”起来,等待jvm中回收机制去回收,形式如下:
正向输出和逆向输出终于保持一致了!
完整代码如下:
class Link
{
public long dData;
public Link next;
public Link previous;
//-------------------
public Link(long d)
{
dData = d;
}
//-------------------
public void displayLink() //display this link;
{
System.out.print(dData + " ");
}
}
//
class DoublyLinkedList
{
private Link first;
private Link last;
//----------------------
public DoublyLinkedList()
{
first = null;
last = null;
}
//----------------------
public boolean isEmpty()
{
return first == null;
}
//---------------------
public void insertFirst(long dd)
{
Link newLink = new Link(dd);
if(isEmpty())
{
last = newLink;
}
else
{
first.previous = newLink;
}
newLink.next = first;
first = newLink;
/* This part is designed by me, I may right!
if(isEmpty())
{
first = newLink;
last = newLink;
}
else
{
first.previous = newLink;
newLink.next = first;
first = newLink;
}*/
}
//--------------------
public void insertLast(long dd) //by me!
{
Link newLink = new Link(dd);
if(isEmpty())
{
first = newLink;
last = newLink;
}
else
{
last.next = newLink;
newLink.previous = last;
last = newLink;
}
}
//------------------------------------------by me!
public Link deleteFirst()
{
Link temp = first; // what I designed support emtpy list
if(first == null) // an empty list
{
System.out.println("Your list is an empty one, nothing to delete");
return null;
}
if(first.next == null) //just one item is the list
{
last = null;
first = null;
}
else
{
first.next.previous = null;
first = first.next;
}
return temp;
}
//-------------------------------------------
public Link deleteLast()
{
Link temp = last; //save the last one ! what I designed support emtpy list
if(last == null) //an empty list
{
System.out.println("Your list is an empty one, nothing to delete");
return null;
}
if(last.previous == null)
{
last = null;
first = null;
}
else
{
last.previous.next = null;
last = last.previous;
}
return temp;
}
//-------------------------------------------
public void insertAfter(long key, long dd) by me! make sure the "key" is already in your list;
{
Link current = first;
Link temp = null;
if(current==null) //the list is an empty one!
{
System.out.println("Your list is am empty one, please insert something first");
return;
}
else
{
while(current.dData!=key && current!=last)
{
current = current.next;
}
}
Link newLink = new Link(dd);
if(current==first)
{
temp = current.next; //these five lins codes can be written just once!
current.next = newLink;
newLink.next = temp;
temp.previous = newLink;
newLink.previous = current;
}
else if(current==last)
{
if (current.dData!=key) {
System.out.println("Cannot find the item according the key you give!");
return ;
}
newLink.previous = current;
current.next = newLink;
last = newLink;
}
else
{
temp = current.next;
current.next = newLink;
newLink.next = temp;
temp.previous = newLink;
newLink.previous = current;
}
}
//-------------------------------------------
public Link deleteKey(long key)
{
Link current = first;
Link currentNext = null;
if(first==null)
{
System.out.println("You have nothing to delete, your list is an empty one!");
return null;
}
else
{
while(current.dData!=key)
{
current = current.next;
if(current==null)
{
System.out.println("You don't have the item in your list");
return null;
}
}
}
if(current==first) //support to delete the first item
{
current.next.previous = null;
first = current.next;
return current;
}
if(current==last)
{
current.previous.next = null;
last = current.previous;
return current;
}
else
{
current.previous.next = current.next;
current.next.previous = current.previous; //what I first wrote is :current.next = current.previous;
return current;
}
}
//--------------------------------------------
public void displayF()
{
System.out.print("List (first-->last): ");
Link current = first;
if(current==null)
{
System.out.print("empty list");
}
while(current!=null) //assume non-empty list
{
current.displayLink();
current = current.next;
}
System.out.println();
}
//---------------------------------------------
public void displayBackword()
{
Link current = last;
System.out.print("List (last-->first): ");
if(current==null)
{
System.out.print("empty list");
}
while(current!=null)
{
current.displayLink();
current = current.previous;
}
System.out.println();
}
}
//-----------------------------------------------------
public class DoublyLinkedApp
{
public static void main(String[] args)
{
DoublyLinkedList list = new DoublyLinkedList();
list.insertFirst(80);
list.insertFirst(70);
list.insertFirst(60);
list.insertLast(21);
list.insertLast(22);
list.insertLast(23);
list.displayForward();
list.displayBackword();
System.out.println(); //leave a line to see the result clearly!
System.out.println("when I insert 564 after the item 12 , the list becomes: ");
list.insertAfter(70,564);
list.displayForward();
list.displayBackword();
System.out.println(); //leave a line to see the result clearly!
System.out.println("when I delete the item 21 and 22 form the list, it becomes: ");
list.deleteKey(21);
list.deleteKey(22);
list.displayForward();
list.displayBackword();
}
}
程序运行结果如下:
本博文代码托管至Github,来Github找我