Java雙向連結串列的實現
阿新 • • 發佈:2019-02-13
最近在複習Java的基礎知識,看到了List時,想起學習C++時,曾用結構體構造有頭連結串列,所以好奇如何使用Java構造連結串列,遂有了如下程式碼:
實現了連結串列的雙向新增,雙向遍歷,刪除值;
本例中,頭結點和尾節點是單獨出來的,value屬性為null,只是為了方便讀取而存在的,不儲存具體的物件;
//連結串列的節點類,MyNode.java
package my;
public class MyNode<T>
{
public T value; //節點值
public MyNode<T> previous;//前一個,如果沒有這個引數的話,不好從後向前遍歷
public MyNode<T> next;
public MyNode(T value)
{
this.value = value;
this.next = null;
this.previous = null;
}
public T getValue()
{
return value;
}
public void setValue(T value)
{
this.value = value;
}
public MyNode<T> getPrevious()
{
return previous;
}
public void setPrevious(MyNode<T> previous)
{
this.previous = previous;
}
public MyNode<T> getNext()
{
return next;
}
public void setNext(MyNode<T> next)
{
this .next = next;
}
}
//連結串列的具體實現類:MyList.java
package my;
//該列表是否可以存放異構物件,去掉本類的泛型是否可以;結論:將T設為Object時,該列表可以存放異構物件,
public class MyList<T>
{
//是否可以先建立一個內部類,在內部類中定義節點屬性;結果:新建了一個節點類,把節點單獨作為一個物件使用;使用內部類也是可以的;
public MyNode head = new MyNode(null);
public MyNode last = new MyNode(null);
public MyList()
{
head.previous = null;
head.next = last;
last.previous = head;
last.previous = null;
}
public void addtoHead(T value)
{
MyNode node = new MyNode(value);
head.next.previous = node;
node.next = head.next;
node.previous = head;
head.next = node;
}
public void addtoLast(T value)
{
MyNode node = new MyNode(value);
last.previous.next = node;
node.previous = last.previous;
node.next = last;
last.previous = node;
}
//刪除節點,使用value,如果加上下標的話,就變成hash表了;刪除第一個相同的value
public void delete(T value) throws Exception
{
MyNode node = head.next;
while(node != null && node != last)
{
if(node.getValue() == value)
{
//刪除
node.previous.next = node.next;
node.next.previous = node.previous;
node = null;
break;
}
node = node.next;
}
boolean isTheLast = node==last;
if(isTheLast)
{
throw new Exception("連結串列中不存在:"+value);
}
//System.out.println("是否為last:"+isTheLast);
}
//連結串列的雙向遍歷
public void printListFromHead() throws Exception
{
MyNode node = head.next;
if(node == last)
{
throw new Exception("連結串列為空");
}
while(node != null && node != last)
{
System.out.println(node.getValue() + "");
node = node.next;
}
}
public void printListFromLast() throws Exception
{
MyNode node = last.previous;
if(node == head)
{
throw new Exception("連結串列為空");
}
while(node != null && node != head)
{
System.out.println(node.getValue() + "");
node = node.previous;
}
}
public MyNode getHead()
{
return head;
}
public void setHead(MyNode head)
{
this.head = head;
}
public MyNode getLast()
{
return last;
}
public void setLast(MyNode last)
{
this.last = last;
}
}
//測試類:test1.java
package my;
public class test1
{
/**
* 連結串列測試
*
* @param args
*/
public static void main(String[] args)
{
try
{
MyList<String> myList1 = new MyList<String>();
myList1.addtoHead("ppp");
myList1.addtoHead("ssd");
myList1.addtoHead("sdf");
myList1.addtoHead("so");
myList1.addtoHead("123");
myList1.addtoHead("ppp");
System.out.println("-------正向遍歷測試--------");
myList1.printListFromHead();
System.out.println("-------反向遍歷測試--------");
myList1.printListFromLast();
System.out.println("---------刪除測試------------------------------");
myList1.delete("ppp");
myList1.printListFromHead();
System.out
.println("---------是否可以存放異構物件------------------------------");
MyList<Object> myList2 = new MyList<Object>();
myList2.addtoHead("sdf");
myList2.addtoHead(123);
myList2.addtoHead(2323.23);
myList2.addtoHead("sdf");
myList2.addtoHead("123");
myList2.printListFromHead();
try
{
System.out
.println("---------空連結串列異常測試------------------------------");
MyList<String> myList0 = new MyList<String>();
myList0.printListFromHead();// 出現異常,直接跳轉至catch中執行;
} catch (Exception e)
{
e.printStackTrace();
}
} catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}