编程之美3.6 判断单链表是否存在环,判断两个链表是否相交问题详解

推荐http://blog.csdn.net/ldong2007/article/details/4544203

http://www.cnblogs.com/kurtwang/archive/2010/09/22/1833106.html

自己的

扩展问题:
判断两个单链表是否相交,如果相交,给出相交的第一个点(两个链表都不存在环)。


#include <iostream>  
using namespace std;  
struct Node{  
    int data;  
    Node* next;  
};  
void insertope(Node* &head,int a){//插入一个元素  
    Node *newp = new Node();  
    newp->data = a;  
    newp->next = NULL;  
    Node *p = head;  
    while(p->next){  
        p = p->next;  
    }  
    p->next = newp;  
}  
void deleteope(Node* &head){//删除头元素  
    Node *p = head->next;  
    head->data = p->data;  
    head->next = p->next;  
    delete p;  
}  
void prints(Node *head){//打印整个链表  
    while(head){  
        cout<<head->data<<" ";  
        head = head->next;  
    }  
    cout<<endl;  
}  
void inverse(Node *&head){//将单链表中的元素顺序反转过来  
    Node *p = head;  
      
    Node *q = head->next;  
    p->next = NULL;  
    Node * temp;  
    while(q){  
        temp = q->next;  
        q->next=p;  
        p=q;  
        q=temp;  
    }  
    head = p;  
}  
void insertss(Node *&head,Node *newp){
	Node *p = head;
	while(p->next){  
        p = p->next;  
    }  
    p->next = newp; 
}
//通过最后一个节点判断两个链表是不是有重合
void check1(Node *head1,Node *head2){
	Node *p = head1;
	while(p->next){
		p = p->next;
	}
	Node *p2 = head2;
	while(p2->next){
		p2 = p2->next;
	}
	if(p==p2)
		cout<<"loop"<<endl;
	else cout<<"no loop"<<endl;
}
//将一个A链表闭合,然后从另一个B链表循环,如果有节点地址和A链表头相等,那么两个链表有环
void check2(Node *head1,Node *head2){
	Node *p = head1;
	while(p->next){
		p = p->next;
	}
	p->next = head1;
	Node *p2 = head2;
	while(p2->next){
		if(p2==head1){
			cout<<"loop"<<endl;
			p->next = NULL;
			return;
		}
		p2 = p2->next;
	}
	cout<<"no loop"<<endl;
}
//找两个链表中的第一个相交点
void getfirst(Node *head1,Node *head2){
	Node *p1 = head1;
	int c1 = 1;
	while(p1->next){
		c1++;
		p1 = p1->next;
	}
	Node *p2 = head2;
	int c2 = 1;
	while(p2->next){
		c2++;
		p2 = p2->next;
	}
	p1 = head1;
	p2 = head2;
	if(c1>c2){
		int step = c1-c2;
		while(p1->next){
			p1 = p1->next;
			if(step<=0)
				p2 = p2->next;
			step--;
			if(p1==p2){
				cout<<p1->data<<endl;
				return ;
			}
		}

	}
}
//当有一个链表,有环时候,判断环的入口地址a=(n-1)r+L-a-x
void getfirstloop(Node *&head){
	Node *slow = head,*fast = head;
	while(true){
		slow = slow->next;
		fast = fast->next->next;
		if(slow==fast){
			slow = head;
			while(true){
				slow = slow->next;
				fast = fast->next;
				if(slow==fast){
					cout<<slow->data<<endl;
					return;
				}
			}

		}
	}
}
int main(){  
    Node * head1 = new Node();  
	//Node * head2 = new Node();  
    head1->data = 11;  
    head1->next = NULL;  
	//head2->data = 21;  
    //head2->next = NULL;
    insertope(head1,12);  
    insertope(head1,13); 

	Node *cp1 = new Node();
	Node *cp2 = new Node();
	cp1->data=91;
	cp2->data=92;
	cp1->next = NULL;
	cp2->next = cp1;

	insertss(head1,cp1);
	insertope(head1,14); 
	insertope(head1,15); 
	insertope(head1,16); 
	insertope(head1,17);
	insertss(head1,cp2);


	//insertope(head2,22);  
    //insertope(head2,23);  

	getfirstloop(head1);
	
	//insertss(head1,cp1);
	//insertss(head1,cp2);
	//insertss(head2,cp1);

    //prints(head1);  
	//prints(head2);  
    //getfirst(head1,head2);
    return 0;  
  
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值