question:
1.判断单链表是否带环?若带环,求环的长度?求环的入口点?并计算每个算法的时间复杂度&空间复杂度。
2.判断两个链表是否相交,若相交,求交点。(假设链表不带环)
3.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】
4.复杂链表的复制。一个链表的每个节点,有一个指向next指针指向下一个节点,还有一个random指针指向这个链表中的一个随机节点或者NULL,现在要求实现复制这个链表,返回复制后的新链表。
//ps: 复杂链表的结构
struct ComplexNode
{
int _data ; // 数据
struct ComplexNode * _next; // 指向下一个节点的指针
struct ComplexNode * _random; // 指向随机节点(可以是链表中的任意节点 or 空)
};
answer:
1.判断单链表是否带环?若带环,求环的长度?求环的入口点?并计算每个算法的时间复杂度&空间复杂度。
ListNode *IsCysle(ListNode *list) //判断单链表是否带环,返回交点
{
ListNode* slow = list;
ListNode* fast = list;
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if (fast == slow)
{
return slow;
}
}
return NULL;
}
int GetCyclelen(ListNode *list) //环的长度
{
ListNode* fast = IsCysle(list);
if (fast!=NULL)
{
int count = 1;
ListNode* slow = fast;
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if (fast == slow)
{
break;
}
count++;
}
return count;
}
else
{
return 0;
}
}
ListNode* GetCyclenEnrty(ListNode* list,ListNode* meetNode) //求环入口点
{
assert(list && meetNode);
while(1)
{
if (list == meetNode)
{
return list;
}
list = list->next;
meetNode = meetNode->next;
}
}
2.判断两个链表是否相交,若相交,求交点。(假设链表不带环)
bool CheckIsMeet(ListNode* list1,ListNode* list2) //判断链表相交
{
ListNode* tail1 = list1;
ListNode* tail2 = list2;
while (tail1->next)
{
tail1 = tail1->next;
}
while (tail2->next)
{
tail2 = tail2->next;
}
if (tail1 = tail2)
{
return true;
}
else
{
return false;
}
}
ListNode* GetMeetNode(ListNode* list1,ListNode* list2) //求相交点
{
ListNode* cur1 = list1;
ListNode* cur2 = list2;
ListNode* longlist = list1;
ListNode* shortlist = list2;
int len1 = 0;
int len2 = 0;
int gap = 0;
while (cur1)
{
len1++;
cur1 = cur1->next;
}
while (cur2)
{
len2++;
cur2 = cur2->next;
}
if (len1 < len2)
{
longlist = list2;
shortlist = list1;
}
gap = abs(len1 - len2);
while (gap--)
{
longlist = longlist->next;
}
while (longlist)
{
if (longlist == shortlist)
{
return longlist;
}
longlist = longlist->next;
shortlist = shortlist->next;
}
return NULL;
}
3.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)
ListNode *CheckIsMeetRing(ListNode *list, ListNode *plist)
{
ListNode* cur1 = GetCyclenEnrty(list);
ListNode* cur2 = GetCyclenEnrty(plist);
//两个链表都不带环
if ((cur1 == NULL) && (cur2 == NULL))
{
return GetMeetNode(list, plist);
}
//一个带环,一个不带环(不可能相交)
else if (((cur1 == NULL) && cur2) || ((cur2 == NULL) && cur1))
{
return NULL;
}
//两个都带环
else
{
{
cur1->next = NULL;
return GetMeetNode(list, plist);//交点
}
else
{
ListNode* cur = cur1->next;
while (cur != cur1)
{
if (cur == cur2)
{
return cur1;
}
cur = cur->next;
}
return NULL; //不相交
}
}
}
4.复杂链表的复制。
typedef struct ComplexNode
{
int _data ; // 数据
struct ComplexNode * _next; // 指向下一个节点的指针
struct ComplexNode * _random; // 指向随机节点(可以是链表中的任意节点 or 空)
}ComplexNode;
ComplexNode* splitComplexList(ComplexNode * pList);
ComplexNode* BuyComplexNode(int d)
{
ComplexNode* ptr = (ComplexNode*)malloc(sizeof(ComplexNode));
if(ptr == NULL){
perror("malloc");
exit(1);
}
ptr->_data = d;
ptr->_next = NULL;
ptr->_random = NULL;
return ptr;
}
void CopyComplexList(ComplexNode* pList)
{
ComplexNode* tmp = pList;
ComplexNode* newList = pList;
if(pList == NULL || pList->_next == NULL)
return;
//插入节点,在每两个节点之间插入一个节点,数据与前一个相同
while(tmp)
{
ComplexNode* next = pList->_next;
ComplexNode* insert = BuyComplexNode(tmp->_data);
insert->_next = tmp->_next;
tmp->_next = insert;
tmp = insert->_next;
}
//复杂链表的复制
newList = pList;
while(newList)
{
ComplexNode* newcomplexnode = newList->_next;
if(newList->_random != NULL)
{
newcomplexnode->_random = newList->_random->_next;
}
newList = newcomplexnode->_next;
}
}
//链表分离
ComplexNode* splitComplexList(ComplexNode* pList)
{
ComplexNode* tmp = pList;
ComplexNode* list =NULL;
ComplexNode* newlist = NULL;
if(pList != NULL)
{
list = newlist = tmp->_next;
tmp->_next = list->_next;
tmp = tmp->_next;
}
while(tmp)
{
newlist->_next = tmp->_next;
newlist = newlist->_next;
tmp->_next = newlist->_next;
tmp = tmp->_next;
}
return list;
}