带环单链表——题集(三)

带环单链表——题集(三)

       今天分享一下与带环单链表相关的题。分别为:判断链表是否带环若带环求环的长度若带环求环的入口点;并计算以上每个问题的时间复杂度。其次是设计一个类不能被继承;设计一个类只能在堆上创建对象;设计一个类只能在栈上创建对象

       判断链表是否带环;若带环求环的长度;若带环求环的入口点;计算以上每个问题的时间复杂度

源代码:

#include<iostream>
using namespace std;
 
struct ListNode{
int val;
ListNode* next;
ListNode(int _val)
:val(_val)
,next(NULL)
{}
};
 
//判断链表是否带环;
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;
}
 
//若带环求环的长度;
int Looplength(ListNode* met){//判断有环的前提下
int len=1;//met结点即目前环的长度为一
ListNode* cur =met->next;
 
 
while(cur != met){
cur=cur->next;
len++;
}
 
return len;
}
 
//若带环求环的入口点;
ListNode* LoopEnter(ListNode* l1,ListNode*& met){//判断有环的前提下
ListNode* begin=l1;
ListNode* entrance = met;
 
while(begin != entrance){//从相遇点遍历一遍
begin=begin->next;
if(begin == entrance) break;
entrance=entrance->next;
}
 
return entrance;
}
 
void Listtestloop(){//判断链表是否带环;若带环求环的长度;若带环求环的入口点;
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* met=NULL;
bool flag = Isloop(&lA1, met);//判断链表是否带环;
if(flag){//链表带环;
cout<<"Isloop(&lA1, met): "<<flag<<endl;
cout<<"met:"<<met->val<<endl;//由有环得到的相遇结点//很关键
cout<<"Looplength(met): "<<Looplength(met)<<endl;//若带环求环的长度;
cout<<"LoopEnter(&lA1, met): "<<LoopEnter(&lA1, met)->val<<endl;//若带环求环的入口点;
}
else{
cout<<"Isloop(&lA1, met): "<<flag<<endl;//链表不带环;
cout<<"遍历链表l1: ";
Printf(&lA1);
cout<<endl;
}
 
 
met=NULL;
flag = Isloop(&lB1, met);//判断链表是否带环;
if(flag){//链表带环;
cout<<"Isloop(&lB1, met): "<<flag<<endl;
cout<<"met:"<<met->val<<endl;//由有环得到的相遇结点//很关键
cout<<"Looplength(met): "<<Looplength(met)<<endl;//若带环求环的长度;
cout<<"LoopEnter(&lB1, met): "<<LoopEnter(&lB1, met)->val<<endl;//若带环求环的入口点;
}
else{
cout<<"Isloop(&lB1, met): "<<flag;//链表不带环;
Printf(&lB1);
cout<<endl;
}
}
 
int main(){
Listtestloop();//判断链表是否带环;若带环求环的长度;若带环求环的入口点;
 
system("pause");
return 0;
}

运行结果:

 

求解时间复杂度:


       由上可知,判断链表是否带环的时间复杂度为O(N^2);若带环求环的长度的时间复杂度为:O(1);若带环求环的入口点的时间复杂度为O(N^2):。

       接下来是,设计一个类不能被继承;设计一个类只能在堆上创建对象;设计一个类只能在栈上创建对象。

设计一个类不能被继承

      1>将类的构造函数设为private即可。

      2>在类中定义一个接口让内部对象去调用构造函数。源代码:

源代码:

#include<iostream>
using namespace std;
 
//设计一个类不能被继承;
class Exp{
private:
Exp(int val=0)
:a(val)
{
}
public:
static Exp getExp(int val){
return Exp(val);
}
 
void Print(){
cout<<"exp->"<<a<<endl;
}
int a;
};
 
//class exc:public Exp//不能继承
//{
//public:
//exc(int val=1,int tmp=2)
//:b(tmp)
//{}
//int b;
//};
 
void testexp()
{
cout<<"类不能被继承"<<endl;
Exp p=Exp::getExp(8);
p.Print();
p.a=4;
p.Print();
}
 
int main(){
testexp();//设计一个类不能被继承;
 
system("pause");
return 0;
}

运行结果:

 

Exp类正常运行

 

exc类不能继承Exp类,编译不通过

设计一个类只能在堆上创建对象:

      1>将类的构造函数设为private。

      2>在类中定义一个接口让内部对象去调用构造函数。

源代码:

#include<iostream>
using namespace std;
 
//设计一个类只能在堆上创建对象
class Exp1{
private:
Exp1(int val=0)
:a(val)
{
}
public:
static Exp1* getExp(int val){
return new Exp1;
}
void Print(){
cout<<"exp->"<<a<<endl;
}
int a;
};
 
void testexp()
{
cout<<"类只能在堆上创建对象"<<endl;
Exp1* p1=Exp1::getExp(8);
p1->a=2;
p1->Print();
}
 
int main(){
testexp();
 
system("pause");
return 0;
}

运行结果:

 

设计一个类只能在栈上创建对象。

      1>将类的构造函数设为private。

      2>在类中定义一个函数返回临时对象。

源代码:

#include<iostream>
using namespace std;
 
//设计一个类只能在栈上创建对象。
class Exp2{
private:
Exp2(int val=0)
:a(val)
{
}
public:
static Exp2 getExp(int val){
return Exp2(val);
}
void Print(){
cout<<"exp->"<<a<<endl;
}
int a;
};
 
void testexp()
{
cout<<"类只能在栈上创建对象"<<endl;
Exp2 p1=Exp2::getExp(8);
p1.Print();
p1.a = 11;
p1.Print();
}
 
int main(){
testexp();
 
system("pause");
return 0;
}

运行结果:

 


       分享如上,如有错误,望评论斧正!望共同进步!各位洗洗睡吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值