判断链表相交,删除无头单链表的非尾节点及倒序打印单链表——题集(四)

判断链表相交,删除无头单链表的非尾节点及倒序打印单链表——题集(四)

       博主昨天懒丢了,耽搁了昨天的题集更新,所以今天的题集分享可能有点长,首先判断链表相交并求交点的情况,其次删除无头单链表的非尾节点倒序打印单链表

       在链表带环不带环的情况下,分别判断两个链表是否相交,若相交,求交点。

源代码如下:

#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);//删除非尾结点
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;
}

运行界面

 

      分享如上,望共同进步!如有错误,望斧正!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章