判断链表相交,删除无头单链表的非尾节点及倒序打印单链表——题集(四)
2017-07-17 12:07
711 查看
判断链表相交,删除无头单链表的非尾节点及倒序打印单链表——题集(四)
博主昨天懒丢了,耽搁了昨天的题集更新,所以今天的题集分享可能有点长,首先判断链表相交并求交点的情况,其次删除无头单链表的非尾节点及倒序打印单链表。
在链表带环和不带环的情况下,分别判断两个链表是否相交,若相交,求交点。
源代码如下:
运行界面及详解
![](https://oscdn.geek-share.com/Uploads/Images/Content/201707/17/6a658a7b86bcbdda484f7158d6245858)
删除无头单链表的非尾节点和倒序打印单链表的源代码和运行界面。
源代码如下:
运行界面
![](https://oscdn.geek-share.com/Uploads/Images/Content/201707/17/79751d1cd02ac51d34d89f25477c9caf)
分享如上,望共同进步!如有错误,望斧正!
博主昨天懒丢了,耽搁了昨天的题集更新,所以今天的题集分享可能有点长,首先判断链表相交并求交点的情况,其次删除无头单链表的非尾节点及倒序打印单链表。
在链表带环和不带环的情况下,分别判断两个链表是否相交,若相交,求交点。
源代码如下:
#include<iostream> using namespace std; #include<stack> struct ListNode{ int val; ListNode* next; ListNode(int _val) :val(_val) ,next(NULL) {} }; //判断两个链表是否相交,若相交,求交点。(链表不带环) bool intersect(ListNode* l1, ListNode* l2, ListNode*& met){//链表不带环若相交,求交点 if(l1== NULL || l2== NULL)return false; stack<ListNode*> s1; stack<ListNode*> s2; //全部放入栈中 while(l1->next != NULL){ s1.push(l1); l1=l1->next; } s1.push(l1);//别忘了最后一个元素 while(l2->next !=NULL){ s2.push(l2); l2=l2->next; } s2.push(l2);//别忘了最后一个元素 while(!s1.empty() && !s2.empty() && s1.top() == s2.top()){ met=s1.top(); s1.pop(); s2.pop(); } if(met==NULL){ return false; } return true; } //判断链表是否带环,并用met带出相遇点;前一篇博客中有,哎,我还是粘一下吧。 bool Isloop(ListNode* l1,ListNode*& met){ ListNode* fast=l1; ListNode* low=l1; do{ int i=0; while(i<2){//fast走两步,low走一步,后再判断是否相等。 if(fast->next != NULL){ fast=fast->next; i++; } else{ return false; } } low=low->next; }while(fast != low); met=fast; return true; } //判断两个链表是否相交,若相交,求交点。(链表带环) bool intersect2(ListNode* l1, ListNode* l2, ListNode*& met1, ListNode*& met2){//链表带环若相交,求交点 stack<ListNode*> s1; stack<ListNode*> s2; while(l1->next !=NULL){ s1.push(l1); if(l1==met1) break; l1=l1->next; } if(l1->next ==NULL)return false; int num=0; while(l2->next !=NULL){ s2.push(l2); if(l2==met1) break; if(l2==met2){ num++; if( num > 1) break;//循环一遍还是没有找到切入点,两个链表就不可能相交了 } l2=l2->next; } if(l2->next ==NULL || num > 1)return false; while(!s1.empty() && !s2.empty() && s1.top() == s2.top()){ met1=s1.top(); s1.pop(); s2.pop(); } return true; } void test(ListNode* lA1, ListNode* lB1){//判断相交的一系列操作 ListNode* met1=NULL; ListNode* met2=NULL; bool P1=Isloop( lA1, met1); bool P2=Isloop( lB1, met2); if(!P1 && !P2)//两链表都不带环//判断链表是否带环 { //met1=NULL; if(intersect(lA1, lB1, met1))//链表不带环,若相交,求交点 { cout<<"两链表都不带环,且相交,交点为:"<<met1->val<<endl; } else{ cout<<"两链表都不带环,且不相交"<<endl; } } else if(P1 && P2){//两链表都带环//判断链表是否带环 if(intersect2(lA1, lB1, met1, met2))//链表带环,若相交,求交点 { cout<<"两链表都带环,且相交,交点为:"<<met1->val<<endl; } else{ cout<<"两链表都带环,且不相交"<<endl; } } else{ cout<<"两链表不相交"<<endl; } } void Testinters(){//判断两个链表是否相交,若相交,求交点,分别考虑带环和不带环的情况 ListNode lA1(1); ListNode lA2(2); ListNode lA3(3); ListNode lA4(4); ListNode lA5(11); lA1.next = &lA2; lA2.next = &lA3; lA3.next = &lA4; lA4.next = &lA5; ListNode lB1(7); ListNode lB2(3); ListNode lB3(8); ListNode lB4(4); ListNode lB5(11); lB1.next = &lB2; lB2.next = &lB3; lB3.next = &lB4; lB4.next = &lB5; lB5.next = &lB2; ListNode lC1(7); ListNode lC2(3); ListNode lC3(8); ListNode lC4(4); ListNode lC5(11); lC1.next = &lC2; lC2.next = &lC3; lC3.next = &lC4; lC4.next = &lC5; lC5.next = &lC2; cout<<"test(&lA1, &lB1): "; test(&lA1, &lB1); cout<<"test(&lA1, &lA2): "; test(&lA1, &lA2); cout<<"test(&lB1, &lB3): "; test(&lB1, &lB3); cout<<"test(&lB1, &lB5): "; test(&lB1, &lB5); cout<<"test(&lB1, &lC5): "; test(&lB1, &lC5); cout<<"test(&lB1, &lC1): "; test(&lB1, &lC1); } int main(){ Testinters();//判断两个链表是否相交,若相交,求交点,分别考虑带环和不带环的情况 system("pause"); return 0; }
运行界面及详解
删除无头单链表的非尾节点和倒序打印单链表的源代码和运行界面。
源代码如下:
#include<iostream> using namespace std; struct ListNode{ int val; ListNode* next; ListNode(int _val) :val(_val) ,next(NULL) {} }; bool DeleteP(ListNode* del){//删除非尾结点 if(del->next == NULL){ cout<<"要删除的结点为尾结点,不符合要求"<<endl; return false; } //在头,在中间——替换 ListNode* next = del->next; del->val = next->val; del->next = next->next; //结构体没有析构,不用手动删除next结点; return true; } //从头到尾打印单链表 void Printf(ListNode* l1){//打印 while(l1!=NULL){ cout<<l1->val<<" "; l1=l1->next; } printf("\n"); } //从尾到头打印单链表 void ReversePrint(ListNode* l1){//逆序打印 if(l1->next != NULL) ReversePrint(l1->next); cout<<l1->val<<" "; } void TestPrint(){ ListNode l1(1); ListNode l2(2); ListNode l3(3); ListNode l4(4); ListNode l5(11); l1.next = &l2; l2.next = &l3; l3.next = &l4; l4.next = &l5; cout<<"正序打印单链表: "; Printf(&l1);//正序打印单链表 cout<<"逆序打印单链表: "; ReversePrint(&l1);//逆序打印单链表 cout<<"\n\n"; cout<<"DeleteP(&l5): "; DeleteP(&l5);//删除非尾 b6bc 结点 cout<<"正序打印单链表: "; Printf(&l1);//正序打印单链表 cout<<"逆序打印单链表: "; ReversePrint(&l1);//逆序打印单链表 cout<<"\n\n"; cout<<"DeleteP(&l3): "; DeleteP(&l3);//删除非尾结点 cout<<"正序打印单链表: "; Printf(&l1);//正序打印单链表 cout<<"逆序打印单链表: "; ReversePrint(&l1);//逆序打印单链表 cout<<"\n\n"; cout<<"DeleteP(&l1): "; DeleteP(&l1);//删除非尾结点 cout<<"正序打印单链表: "; Printf(&l1);//正序打印单链表 cout<<"逆序打印单链表: "; ReversePrint(&l1);//逆序打印单链表 cout<<"\n\n"; } int main(){ TestPrint();//从尾到头打印单链表 system("pause"); return 0; }
运行界面
分享如上,望共同进步!如有错误,望斧正!
相关文章推荐
- 每日一题——删除无头链表的非尾节点、逆向打印单链表
- day05删除一个无头单链表的非尾节点 +从尾到头打印单链表+复杂链表的复制
- 【链表】删除一个无头单链表的非尾节点 以及从尾到头打印单链表
- 1.删除一个无头单链表的非尾节点 2.从尾到头打印单链表
- 单链表的逆向打印、删除无头的非尾节点、无头链表插入节点、约瑟环
- 链表--删除一个无头单链表的非尾节点
- 【链表面试题】删除无头单链表的非尾节点,插入一个元素到无头链表指定位置
- 【链表面试题】删除无头单链表的非尾节点,插入一个元素到无头链表指定位置
- C语言:【单链表】删除一个无头单链表的非尾节点
- 链表面试题逆序打印,删除无头非尾节点,非头位置插入,约瑟夫环,查找中间和倒数第k个节点
- 每日一刷——删除无头链表非尾结点&倒序打印链表
- 1.删除一个无头单链表的非尾节点 2.从尾到头打印单链表
- C语言:【单链表】删除一个无头单链表的非尾节点
- 17_7_17:删除一个无头单链表的非尾节点。从尾到头打印单链表
- 笔试/面试:删除一个无头单链表的非尾节点 ,从尾到头打印单链表
- 删除一个无头单链表的非尾节点+从尾到头打印单链表
- 链表面试题(一):逆序打印链表、无头链表删除插入节点、约瑟夫环、逆置单链表
- 单链表的创建和遍历、求单链表中节点的个数、查找单链表中的中间结点、判断单链表是否有环、取出有环链表中环的长度,删除有序链表中的重复结点
- 单链表中头结点的有无. 并讨论下有无头结点在单链表的创建,打印,插入,逆置,删除中的区别.
- 删除一个无头单链表的非尾节点