线性表的每个节点包含一个数据项(data)和指针(Java的对象引用),数据结构如下:
public class Node<T> //自引用类:一个类申明包含一个引用当前类的对象的成员变量
{
public T data;//为了方便更改节点间的链接关系,将这两个成员变量申明为public,允许其他类访问
public Node<T> next;
public Node(T data,Node<T>next)
{
this.data=data;
this.next=next;
}
public Node()
{
this(null,null);
}
}
注意:链表(单向链表)的头部是一个无真实数据项的节点:
public class SinglyLinkedList<T> implements LList<T>
{
protected Node<T> head;
public SinglyLinkedList()
{
this.head=new Node<T>();
//默认构造函数构造空单链表(头结点不存储数据项),只有头结点,数据项和引用项均为null
}
public SinglyLinkedList(SinglyLinkedList<T> list)//单链表浅拷贝
{
this.head=list.head;
}
public SinglyLinkedList(T[] element)//
{
this();
Node<T> rear=this.head;
for(int i=0;i<element.length;i++)
{
rear.next=new Node<T>(element[i],null);
rear=rear.next;
}
}
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return this.head.next==null;//带头结点的链表中,除了头结点没有后续节点则为空
}
@Override
public int length() {
// TODO Auto-generated method stub
int i=0;
Node<T> p=this.head.next;
while(p!=null)
{
i++;
p=p.next;
}
return i;
}
public String toString()
{
Node<T> p=this.head.next;
String str="(";
while(p!=null)
{
str+=p.data.toString();
if(p.next!=null)
str+=",";
p=p.next;
}
return str+")";
}
@Override
public T get(int i)
{
if(i>=0)
{
Node<T> p=this.head.next;
for(int j=0;p!=null && j<i;j++)
p=p.next;
if(p!=null)
return p.data;
}
return null;
}
public Node<T> getNode(int i)
{
if(i>=0)
{
Node<T> p=this.head.next;
for(int j=0;p!=null && j<i;i++)
p=p.next;
if(p!=null)
return p;
}
return null;
}
@Override
public void set(int i, T x) {
// TODO Auto-generated method stub
if(x==null)
return;
if(i>=0)
{
Node<T> p=this.head.next;
for(int j=0;p!=null&&j<i;j++)
p=p.next;
if(p!=null)
{
p.data=x;
}
}
}
@Override
public void insert(int i, T x) {
// TODO Auto-generated method stub
if(x==null)
return;
Node<T> p=this.head;
Node<T> temp=new Node<T>(x,null);
for(int j=0;p.next!=null&&j<i;j++)
p=p.next;
temp.next=p.next;
p.next=temp;
System.out.println(p.next.data);
}
@Override
public void append(T x) {
// TODO Auto-generated method stub
if(x==null)
return;
Node<T> p=this.head;
Node<T> temp=new Node<T>(x,null);
while(p.next!=null)
p=p.next;
if(x!=null)
p.next=temp;
}
@Override
public T remove(int i)
{
/*
if(i>=0)
{
Node<T> p=this.head;
for(int j=0;p.next!=null&&j<i;j++)
p=p.next;
if(p.next!=null)
{
T old = p.next.data;
p.next=p.next.next;
return old;
}
}
return null;*/
Node<T> p=this.head;
Node<T> temp=null;
if(this.head.next!=null)
{
for(int j=0;p.next!=null&&j<i;j++)//要删除第n个节点,指针遍历到第n-1个
p=p.next;
}
temp=p.next;
p.next=p.next.next;
return temp.data;
}
@Override
public void removeAll() {
// TODO Auto-generated method stub
this.head.next=null;
}
@Override
public int search(T key) {
// TODO Auto-generated method stub
return 0;
}
public void insertAfter(Node<T> p,T x) //O(1)
{
Node<T> t=new Node<T>(x,p.next);
p.next=t;
}
@SuppressWarnings("unchecked")
public boolean equals(Object obj) //覆盖父类Object的equals()方法
{
if(obj==this)
return true;
if(!(obj instanceof SinglyLinkedList))
return false;
Node<T> p=this.head.next;
Node<T> q=((SinglyLinkedList<T>)obj).head.next;
while(p!=null && q!=null &&p.data.equals(q.data))
{
p=p.next;
q=q.next;
}
return p==null && q==null;//当p、q都遍历结束跳出while时都指向了null
}
public void reverse(SinglyLinkedList<T> list)
{
Node<T> p=this.head.next,succ=null,front=null;
while(p!=null)
{
succ=p.next;
p.next=front;
front=p;
p=succ;
}
list.head.next=front;
}
public Node<T> removeNthFromEnd(Node<T> head,int n)
{
Node<T> p=head,temp=null;
int i=1,loc=0;
while(p.next!=null)
{
p=p.next;
i++;
}
p=head;
while(loc<i-n-1)
{
p=p.next;
loc++;
}
temp=p.next;
p.next=p.next.next;
return temp;
}
}
测试代码如下:
public static void main(String[] args) {
// TODO Auto-generated method stub
/*
Node<String> p=new Node<String>("A",null);
Node<String> q=new Node<String>("B",null);
p.next=q;
Node<String> head=null;//单链表的头指针head也是一个节点引用,当head=null时表示空的单链表
*/
SinglyLinkedList<String> slist=new SinglyLinkedList<String>();
slist.insert(0, "Hello");
slist.insert(1, "World");
slist.append("my");//slist.insert(0, "Hello");slist.insert(0, "Hello");
slist.insert(0, "Java");
slist.insert(4, "haha");//尾插检验
System.out.println(slist.toString());
slist.remove(4);
System.out.println(slist.get(2));
System.out.println(slist.toString());
slist.reverse(slist);
System.out.println(slist.toString());
SinglyLinkedList<Integer> list=new SinglyLinkedList<Integer>();
list.append(1);
list.append(2);
list.append(3);
System.out.println(list.toString());
list.reverse(list);
System.out.println("逆转后"+list.toString());
}