采用带头节点的单链表保存单词,返回两个链表共同后缀的起始位置
这里数据域设为int类型,其实String也是一样的
思路一:
1.对于链表str1和str2,分别求出两个链表的长度m和n,
2。p指向str1的头节点,q指向str2的头节点,当m大于等于n,p向后移动m-n+1个节点,当n大于m,q向后移n-m+1,总之,要保证p和q所指的节点到链表尾的长度相等。
3.反复将指针p和q同步后移,并判断它们是否指向同一个节点,若指向同一点,则返回共同后缀的起始位置
</pre><pre name="code" class="java">package pac1;
class Node{
public Node next; //指针域
public int data; //数据域
public Node(int data) {
this.data = data;
}
public void show(){
System.out.print(data+" ");
}
}
public class LinkList {
public Node head; //头节点
public LinkList(){
this.head=null;
}
//头插法创建表,将新节点插入到头结点之后
public void creatList1(LinkList L,int [] arr){
for(int i=0;i<arr.length;i++){
Node node=new Node(arr[i]); //创建一个新节点
node.next = head;
head = node;
}
}
//尾插法创建表
public void creatList2(LinkList L,int [] arr){
addHeadNode(arr[0]);//将第一个元素作为头结点
Node rear=head;
for(int i=1;i<arr.length;i++){
Node node=new Node(arr[i]); //创建一个新节点
rear.next= node;
rear=node;
}
}
//显示表
public void showList(){
Node current=head;
while(current!=null){
current.show();
current=current.next;
}
System.out.println();
}
//求两个链表的共同后缀的起始位置
public int findList(LinkList str1,LinkList str2){
int m=0;
Node p=str1.head;
while(p!=null){ //计算str1的长度
m++;
p=p.next;
}
Node q=str2.head;
int n=0;
while(q!=null){ //计算str2的长度
n++;
q=q.next;
}
p=str1.head;
q=str2.head;
if(n>m){ //当str2较长时,q向后移,保证p和q所指的节点到表尾的长度相等
q=str2.head;
int j=0;
while(j<n-m){
j++;
q=q.next;
}
}
else{ //当str1较长时,p向后移,保证p和q所指的节点到表尾的长度相等
p=str2.head;
int k=0;
while(k<m-n){
k++;
p=p.next;
}
}
int mov=0;
//注意这里比较的是节点的地址,而不是节点的值
while(p.next!=null && q.next!=null && p.next!=q.next){
p=p.next;
q=q.next;
mov++;
}
int res=0;
if(n>m) res=n-m+mov;
else res=m-n+mov;
return res;
}
//思路二:串模式匹配算法
public int findList2(LinkList str1,LinkList str2){
Node p=str1.head;
Node q;
int i=0,res=0;
while(p!=null){
i++;
q=str2.head;
while(q!=null){
if(q==p) {res=i;break;}
q=q.next;
}
p=p.next;
}
return res;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int [] arr={1,2,3,4,5};
LinkList L=new LinkList();
L.creatList2(L, arr);
L.showList();
//
int [] arr2={7,8,4,5};
LinkList L2=new LinkList();
L2.creatList2(L2, arr2);
L2.showList();
System.out.println(L.findList1(L, L2));
}
}
思路一的时间复杂度是O(m+n)
思路二:采用串模式匹配的思想。p指向str1,q指向str2,遍历str2,查找str2是否有和p指向的当前节点相同的节点。
现在存在的问题:
思路一可正常运行,通过p.next!=q.next 比较节点的地址是成立的,在思路二中当p、q指向的节点都是4时,判断条件p==q仍然为false,显然p和q指向的不是同一地址,但是p.next和q.next是可以判断出指向的是同一地址,不知其所以然。