带环单链表——题集(三)
今天分享一下与带环单链表相关的题。分别为:判断链表是否带环;若带环求环的长度;若带环求环的入口点;并计算以上每个问题的时间复杂度。其次是设计一个类不能被继承;设计一个类只能在堆上创建对象;设计一个类只能在栈上创建对象。
判断链表是否带环;若带环求环的长度;若带环求环的入口点;并计算以上每个问题的时间复杂度。
源代码:
#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;
}
运行结果:
分享如上,如有错误,望评论斧正!望共同进步!各位洗洗睡吧!