1. 求两个单链表是否相交,如果相交,求出交点
a: 所有结点地址比较
b:对链表1使用hash算法存储,依次查找链表2结点的地址,如果找到,则相交,否则不相交,此方法虽然效率尚可,但是占用空间很大,属于使用空间换效率的方法。
c:将链表2接在链表1后面,判断链表是否有环,如果有,则相交,最后,当然不要忘记恢复原来状态,去掉第一个链表到第二个链表头的指向。
d:判断交点d1:分别求链表1,2的长度x,y,链表1逆序,遍历链表2记下其长度z,则可列出一个x,y,z的方程,求出链表1或者2到结点的距离。
e: 判断交点d2:分别求链表1,2的长度x,y,假设x>y,则让链表1先前进x-y部,然后两个链表同时单步前进,并比较地址,如果相等,则为交点,返回。
bool hasCircle(slist *head)
{
slist *slow = head, *fast = head;
while ( fast && fast->next )
{
slow = slow->next;
fast = fast->next->next;
if ( slow == fast ) break;
}
return !(fast == NULL || fast->next == NULL);
}
2. 求两个链表是否相交,如果相交,求出交点(存在环)
a) 链表1单步前进,链表2双步前进,当链表2的next指针等于链表一的当前地址时,两者相交
b)求交点,从a中的一点,将换断开,逆序链表1,此时相当于生成3个新的链表,只要求出这三个链表的交点,链表1还原,再判断生成的两个不同交点,是否在链表2上
3. 己知两个链表相交(如Y的形状),找出其第一个交点
假设两条链表有公共节点Node, 那么从Node往后的节点必定都是公共节点.也就是这两个链表成"Y"的形状.那么两个链表的长度差只会出现在Node之前.因此,我们求出两个链表的长度,然后用长的减去短的长度,然后让长的那个先跑这个差值后,然后两个表在开始时行比较。
4. 判断一条单链表是否存在环
使用一步二步法可以判断一条单链表是否存在环。使用两个指针同时指向链表的head,一个指针每次走一步,另一指针每次走两步。如果快指针的地址为NULL了,说明表中不存在环,如果快指针指向的地址与慢指针指向的地址一致,说明存在环。
bool IsExitsLoop(slist *head){
slist *slow = head, *fast = head;
while ( fast && fast->next ) {
slow = slow->next;
fast = fast->next->next;
if ( slow == fast ) break;
}
return !(fast == NULL || fast->next == NULL);
}
5. 求出存在环的单链表环的起点
可以使用两步一步法,找到两个指针重合的地方。再将快指针移至单链表的头节点处,每次只走一步,同时快指针也在环上每次只走一步。当两个指针再次相遇时,相遇点就为环的起点。
slist* FindLoopPort(slist *head){
slist *slow = head, *fast = head;
while ( fast && fast->next ) {
slow = slow->next;
fast = fast->next->next;
if ( slow == fast ) break;
}
if (fast == NULL || fast->next == NULL)
return NULL;
slow = head;
while (slow != fast){
slow = slow->next;
fast = fast->next;
}
return slow;
}