思路:
计算链表长度,先让p走差值步,然后两个同时往后步,走到地址相同,则找到。
代码实现
public class Link<T extends Comparable<T>> {
private Entry<T> headEntry;
private Entry<T> tailEntry;//标记尾部
public Entry<T> getEntry(T value){
for(Entry<T> p = headEntry;p!=null;p=p.getNext()){
if(p.getValue().compareTo(value) ==0){
return p;
}
}
return null;
}
public void addHead(T value){
Entry<T> p=new Entry<>(value);
//空链表
if(headEntry==null){
headEntry=p;
tailEntry=p; //标记尾巴
}else {
p.setNext(headEntry);
headEntry=p;//新链表起始位置
}
}
public void addTail(T value){
Entry<T> newEntry=new Entry<>(value);
if(headEntry ==null){
headEntry= newEntry;
tailEntry= newEntry;
}else {
tailEntry.setNext(newEntry);
tailEntry=newEntry;
}
}
public void removeHead(){
if(headEntry==null){
return;
}
headEntry.setValue(null);
headEntry=headEntry.getNext();
if(headEntry==null){
tailEntry=null;
}
}
public void removeTail(){
if (headEntry==null){
return;
}
if(headEntry.getNext()==null){
headEntry=null;
tailEntry=null;
return;
}
tailEntry.setValue(null);//防止内存泄漏
//为尾巴找前驱
Entry<T> beforeTail=headEntry;
for(;beforeTail.getNext().getNext()!=null;beforeTail=beforeTail.getNext()){
;
}
//找到尾巴前驱
tailEntry=beforeTail;
tailEntry.setNext(null);//新尾部结点next=null
beforeTail.setNext(null);
}
public void removeValue(T value){
if(headEntry==null){
return;
}
if(headEntry.getValue().compareTo(value)==0){
headEntry.setValue(null);//防止内存泄漏
headEntry=headEntry.getNext();
if(tailEntry==headEntry){
tailEntry=null;
}
return;
}
//p保存要删结点的前驱结点
for(Entry<T>p=headEntry;p.getNext()!=null;p=p.getNext()){
if(p.getNext().getValue().compareTo(value)==0){
p.getNext().setValue(null);//防止内存泄漏
p.setNext(p.getNext().getNext());
tailEntry=p;//此时更新新尾部
break;
}
}
}
public void show(){
for(Entry p=headEntry;p!=null;p=p.getNext()){
System.out.println(p.getValue()+" ");
}
System.out.println();
}
private int getLength(){
int count =0;
for(Entry<T> p=headEntry;p!=null;p=p.getNext()){
count++;
}
return count;
}
public static <E extends Comparable<E>>E getMeetEntry(Link<E>link,Link<E> link2){
//1.统计出链表长度
int length1=link.getLength();
int length2=link2.getLength();
int difference=Math.abs(length1-length2);//长度
//2.长链表先走差值步
Entry<E> longLinkEntry=length1>length2?link.headEntry:link2.headEntry;
Entry<E> shortLinkEntry=length1>=length2?link.headEntry:link2.headEntry;
for(;--difference>=0;longLinkEntry=longLinkEntry.getNext()){
;
}
//3.长短链表同时向后走,直到long==short
for(;longLinkEntry!=null;longLinkEntry=longLinkEntry.getNext(),shortLinkEntry=shortLinkEntry.getNext()){
if(longLinkEntry==shortLinkEntry){
return longLinkEntry.getValue();
}
}
return null;
}
测试部分
public static void main(String[] args) {
Link<Integer> link=new Link<>();
link.addHead(1);
link.addHead(2);
link.addHead(3);
link.addHead(4);
link.addTail(0);
Entry<Integer>meetEntry=link.getEntry(1);
if (meetEntry==null)
return;
Link<Integer> link2=new Link<>();
link2.addHead(4);
link2.addHead(3);
Entry<Integer>entry=link2.getEntry(4);
entry.setNext(meetEntry);
System.out.println(Link.getMeetEntry(link,link2));
link.show();
link2.show();
}