最近在复习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();
}
}
}