单链表若干操作实现

来源:互联网 发布:程序员必须英语好吗 编辑:程序博客网 时间:2024/05/16 17:01

//单链表若干操作实现代码//0.0 单链表求和.递归与非递归算法int GetSum(ListNode *pHead){if(pHead==NULL)return 0;else return pHead->value + GetSum(pHead->next);}int GetSum2(ListNode *pHead){int sum = 0;ListNode *pNode = pHead;while(pNode){sum += pNode->value;pNode = pNode->next;}return sum;}//1.1 单链表逆序,返回头结点ListNode* ReverseList(ListNode *pHead){ListNode *pReverseHead = NULL;ListNode *pNode = pHead;ListNode *pPre = NULL;ListNode *pNext = NULL;while(pNode!=NULL){pNext = pNode->next;if(pNext == NULL)pReverseHead  = pNode;pNode->next  = pPre;pPre = pNode;pNode = pNext;}return pReverseHead;} //1.2 单链表逆序递归实现,返回头结点ListNode* ReverseList2(ListNode *pHead){if(pHead == NULL || pHead->next ==NULL)return pHead;ListNode *pNode = pHead->next;ListNode *newHead = ReverseList2(pNode);pNode->next = pHead;pHead->next = NULL;return newHead;}//2. 给单链表构建环,将尾指针指向第i个元素,若不成功返回falsebool ConstructLoop(ListNode *pHead,int num) //尾节点插入到第num个元素,从1开始计数{ListNode *pNode = pHead;ListNode *pTail = NULL:if(pHead==NULL || num<=0)return false;for(int i = 1; i<num; i++){pNode = pNode->next;if( pNode==NULL ) //链表节点数目小于numreturn false;}pTail = pNode;//从这个节点继续向后遍历到尾部while(pTail->next!=NULL)pTail = pTail->next;pTail->next = pNode;//尾节点指向第num个元素return true;}//3. 检测单链表是否有环,使用快慢指针的方法,两指针相遇则有环bool DetectLoop(ListNode *pHead){ListNode *slow = pHead;ListNode *fast = pHead;while(fast!=NULL && fast->next!=NULL){slow = slow->next;fast = fast->next->next;if(slow == fast)break;}if(fast==NULL || fast->next==NULL)return false;elsereturn true;}//4.1 检测单链表是否有环,有环找到环入口//先通过快慢指针判断有环,得到快慢指针交点//之后从交点和链表头同步向前,得到的新交点就是环入口,证明略ListNode *FindLoopEntrance(ListNode *pHead){ListNode *slow = pHead;ListNode *fast = pHead;while(fast!=NULL && fast->next!=NULL){slow = slow->next;fast = fast->next->next;if(slow == fast)break;}if(fast==NULL || fast->next==NULL)return NULL;slow = pHead;while(slow != fast){slow = slow->next;fast = fast->next; }return slow;}//4.2 检测单链表是否有环,如果有环就解环。//利用set存储每个节点地址,当环出现时候也就是尾节点连接到了新节点,该节点在set集是有存储的bool ElimateLoop(ListNode *pHead){set<ListNode*> nodeset;ListNode *pNode = pHead;ListNode *pPre = NULL:while(pNode!=NULL){if(nodeset.count(pNode)==0) //表明在set集中不存在{nodeset.insert(pNode);}else{//这里也可以用于返回环入口pPre->next = NULL; //此时pPre为尾节点,进行解环return true;}pPre = pNode;pNode = pNode->next;}return false; //没环存在}//4.3 检测是否有环,如果有环返回环的长度int getLoopLength(ListNode *pHead){ListNode *slow = pHead;ListNode *fast = pHead;while(fast!=NULL && fast->next!=NULL){slow = slow->next;fast = fast->next->next;if(slow == fast)break;}if(fast==NULL || fast->next==NULL)return NULL;int length = 1;fast = fast->next->next;slow = slow->next; while(slow != fast){length++;slow = slow->next;fast = fast->next->next; }return length;}//5. 检测两个链表(均无环)是否相交,如果相交返回交点位置//如果两个链表相交一定是Y形相交,只要判断两个链表的最后一个元素是否相等就可以。//如果要找交点,需要知道二者的长度,len1,len2.对于长链表从abs(len2-len1)开始遍历,相同点就是交点//另外,可以将一个链表的尾附加到另一个链表的头部,问题转化为判断新链表是否存在环。ListNode* DetectIntersect(ListNode *p1, ListNode *p2){if(p1==NULL || p2==NULL)return NULL;int len1 = 1 , len2 = 1;ListNode *pNode1 = p1;ListNode *pNode2 = p2;ListNode *temp = NULL;while(pNode1->next != NULL){len1++;pNode1 = pNode1->next;}while(pNode2->next!= NULL){len2++;pNode2 = pNode2->next;}if(pNode1 != pNode2)//尾节点不同return NULL:if(len1 > len2) //使p1指向长链表,p2指向短链表{pos= len1 - len2;pNode1 = p1;pNode2 = p2;}else{pos = len2 - len1;pNode1 = p2;pNode2 = p1;}while(pos){pNode1 = pNode1->next;pos--;}while(pNode1 != pNode2){pNode1 = pNode1->next;pNode2 = pNode1->next;}return pNode1;}




0 0
原创粉丝点击