可以将单链表看成是递归定义的,每个结点的next域指向由后诸结点组成的一条子单链表,最后一个结点的next域指向空链表。此时可以将单链表写成递归算法。
1、构造空链表
public class LinkedRecursion<T> {
public Node<T>head;
//构造函数,构造空链表
public LinkedRecursion(){
this.head=new Node<T>();
}}
2、根据数组构造单链表
//根据指定数组构造链表
public LinkedRecursion(T [] element){
this();
if(element!=null){
this.head.next=create(element,0);
}
}
private Node<T> create(T[] element, int i) {
// TODO Auto-generated method stub
Node<T> p=null;
if(i<element.length){
p=new Node<T>(element[i],null);
p.next=create(element,i+1);
}
return p;
}
运行过程如下:这里假设数组长度为3。
递归的过程相当于从最后一个结点开始一次往前推进,每次递归返回结果在下一次递归时使用,所以我们从i=3,开始看起。
i=3,此时返回值为结点p,且p=null;
i=2, create(element,2+1)函数返回结点null
此时 p.next=create(element,2+1);
i=1,create(element,1+1)函数返回结点2
此时 p.next=create(element,1+1);
i=0, create(element,0+1)函数返回结点1
此时 p.next=create(element,0+1);
所以this.head.next=create(element,0);创建了一个链表。
3.链表的深拷贝(从链表构造单链表)
//根据单链表构造单链表 深拷贝
public LinkedRecursion(LinkedRecursion<T> list){
this();
this.head.next=copy(list.head.next);
}
private Node<T> copy(Node<T> p) {
// TODO Auto-generated method stub
Node<T>q=null;
//和链表的非递归实现类似,同时给出q结点的data域与next域
if(p!=null){
q=new Node<T>(p.data,null);
q.next=copy(p.next);
}
return q;
}
运行过程:
假设list长度为3
i=3时,copy函数返回的q结点是null;
i=2时,q=new Node(p.data,null);
q.next=copy(p.next);导致 并返回结点q
i=1时,q=new Node(p.data,null);
q.next=copy(p.next);导致 并返回结点q
i=0时,,q=new Node(p.data,null);
q.next=copy(p.next);导致 并返回结点q
所以当递归结束后,拷贝了整个链表。
4、判断是否相等
public boolean equals(Object obj){
if(obj==this)
return true;
if(obj instanceof LinkedRecursion){
LinkedRecursion<T> list=(LinkedRecursion<T>) obj;
return equals(this.head.next,list.head.next);
}
return false;
}
private boolean equals(Node<T> p, Node<T> q) {
// TODO Auto-generated method stub
if(p==null&&q==null)
return true;
return p!=null &&q!=null && p.data.equals(q.data) &&equals(p.next,q.next);
}
5、打印整个链表
public String toString(){
return "("+this.toString(this.head.next)+")";
}
private String toString(Node<T> p) {
// TODO Auto-generated method stub
if(p==null)
return "";
String str=p.data.toString();
if(p.next!=null){
str+=",";
}
return str+this.toString(p.next);
}