• 链表面试题(下)


    // 链表带环问题; 是环,返回相遇点
    SListNode* SListIsCycle(SListNode* list){
    	SListNode* fast,*slow ;
    	assert(list);
    	fast = list->_next;
    	slow = list->_next;
    	while(fast&&fast->_next){
    		slow=slow->_next;
    		fast=fast->_next->_next;
    //		printf("%d,%d
    ",slow->_data,fast->_data);
    		if(slow==fast) 
    			return fast;
    	}
    	return NULL;
    }
    
    //求环长度
    int SListCycleLen(SListNode* meetNode) {
    	int count=0;
    	SListNode *cur;
    	assert(meetNode);
    	cur = meetNode->_next;
    	count++;
    	while(cur!=meetNode){
    		cur=cur->_next;
    		count++;
    	}
    	return count;
    }
    
    //返回环的入口点
    SListNode* SListEntryNode(SListNode* list, SListNode* meetNode){
    	SListNode* head,*cur;
    	assert(list&&meetNode);
    	head = list->_next;
    	cur = meetNode;
    	while(head!=cur){
    		head=head->_next;
    		cur=cur->_next;
    	}
    	return cur;
    }
    
    
    // 链表相交问题 
    //判断两单链表是否相交,不带环
    int SListIsCrossNode(SListNode* list1, SListNode* list2){
    	SListNode* cur1,*cur2;
    	assert(list1&&list2);
    	cur1=list1->_next;
    	cur2=list2->_next;
    	while(cur1->_next)
    		cur1=cur1->_next;
    	while(cur2->_next)
    		cur2=cur2->_next;
    	if(cur1==cur2)
    		return 1;
    	return 0;
    }
    //返回相交点
    SListNode* SListCrossNode(SListNode* list1, SListNode* list2){
    	int len1,len2,t;
    	SListNode* cur1,*cur2;
    	assert(list1&&list2);
    	cur1=list1->_next;
    	cur2=list2->_next;
    	len1=SlistLenth(list1);
    	len2=SlistLenth(list2);
    	if(len1==len2){
    		while(cur1!=cur2){
    			cur1=cur1->_next;
    			cur2=cur2->_next;
    		}
    		return cur1;
    	}
    	else if(len1>len2){
    		t=len1-len2;
    		while(t--){
    			cur1=cur1->_next;
    		}
    		while(cur1!=cur2){
    			cur1=cur1->_next;
    			cur2=cur2->_next;
    		}
    		return cur1;
    	}
    	else {
    		t=len2-len1;
    		while(t--){
    			cur2=cur2->_next;
    		}
    		while(cur1!=cur2){
    			cur1=cur1->_next;
    			cur2=cur2->_next;
    		}
    		return cur1;
    	}
    }
    //判断两单链表是否相交,(链表可能带环)【升级版】
    int SListIsCrossNodeCycle(SListNode* list1, SListNode* list2){
    	SListNode* M1,*M2,*cur;
    	assert(list1&&list2);
    
    	M1=SListIsCycle(list1);
    	M2=SListIsCycle(list2);
    	if(M1==NULL&&M2==NULL&&SListIsCrossNode(list1,list2)) //1.不带环情况下相交
    		return 1;
    
    	if(M1&&M2){                       //2.两个都是环
    		cur=M1->_next;
    		while(cur!=M1){
    			if(cur==M2)
    				return 1;
    			cur=cur->_next;
    		}
    		if((M1==M2))						
    			return 1;
    	}
    	return 0;
    }
    //返回相交点
    SListNode* SListCrossNodeCycle(SListNode* list1, SListNode* list2){
    	SListNode* M1,*M2,*E1,*E2,*cur1,*cur2;
    	assert(list1&&list2);
    	M1=SListIsCycle(list1);
    	M2=SListIsCycle(list2);
    	cur1=list1->_next;
    	cur2=list2->_next;
    	if(M1==NULL&&M2==NULL&&SListIsCrossNode(list1,list2)){  //不带环
    		return SListCrossNode(list1,list2);
    	}
    	if(SListIsCrossNodeCycle(list1,list2)){
    		E1=SListEntryNode(list1,M1);
    		E2=SListEntryNode(list2,M2);
    		if(E1==E2){           //说明在环外相交
    			E1->_next=NULL;
    			return SListCrossNode(list1,list2);
    		}
    			return E2;
    	}
    	return NULL;
    }
    
    
    
    // 复杂链表复制 
    //struct ComplexListNode 
    //{ 
    //	int _data; 
    //	ComplexListNode* _next; 
    //	ComplexListNode* _random; 
    //}; 
    //
    //ComplexListNode* CopyComplexList(ComplexListNode* list); 
    //void UnionSet(SListNode* l1, SListNode* l2); 
    

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 阿尔法乘积
    Java实现 蓝桥杯VIP 算法训练 黑色星期五
    Java实现 蓝桥杯VIP 算法训练 黑色星期五
    Java实现 蓝桥杯VIP 算法训练 阶乘
    Java实现 蓝桥杯VIP 算法训练 反置数
    Java实现 蓝桥杯VIP 算法训练 新生舞会
    Android消息机制架构和源码解析
    华为接班人制度(效率优先,兼顾公平,可持续发展)
    VMware与宿敌Amazon一笑泯恩仇:重新定义混合云?(私有云节节败退)
    UAC新解(有非正常手段可以绕过)
  • 原文地址:https://www.cnblogs.com/yongtaochang/p/13615373.html
Copyright © 2020-2023  润新知