6. 顺序存储线性表的分析

1. 效率分析

template <typename T>
class SeqList : public List<T>
{
public:
	bool insert(int i,const T& e);//O(n)
	bool remove(int i);			  //O(n)
	bool set(int i,const T& e);   //O(1)
	bool get(int i,T& e) const;	  //O(1)
	int length() const;			  //O(1)
	void clear();				  //O(1)

	T& operator[] (int i);        //O(1)
	T operator[] (int i) const;   //O(1)
	
	virtual int capacity() const = 0;
};

在这里插入图片描述

insert 函数最耗时的地方时for循环,但是不同情况效率一致嘛?
举个例子:

SeqList<int> s1;
SeqList<string> s2;
s1.insert(0,1);
s2.insert(0,"DragonLib");

假设容量都是20,那么很显然小效率是不一致的,s1速度很快,但是s2相当于一个字符一个字符地挪动,效率很低!
结论:效率不只是看时间复杂度,顺序存储的线性表不适合类类型的数据存储

2. 代码分析

2.1 StaticList中的问题

StaticList<int*,5> s1;
StaticList<int*,5> s2;
for(int i=0;i<s1.capacity();i++)
{
	s1.insert(0,new int(i));
}
s2 = s1;		//copy assignment
for(int i =0;i<s1.length();i++)
{
	delete s1[i];
	delete s2[i];
}

s2 = 21;会发生什么呢?
在这里插入图片描述
指针两个数组指向同一个区域。然而在进行delete s1[i];delete s2[i];时,相当于执行了两遍清空操作,这是未定义的,危险行为。

2.2 DynamicList中的问题

void func()
{
	DynamicList<int> d1(5);
	DynamicList<int> d2 = d1;		//copy construct

	for(int i=0;i<d1.capacity();i++)
	{
		d1.insert(i,i);
		d2.insert(i,i*i);
	}
	for(int i=0;i<d1.length();i++)
	{
		cout << d1[i] << endl;
	}
}

在这里插入图片描述
m_array指向同一片区域,析构时,会被释放两次!

3. 如何解决?

3.1 分析

对于容器类型的类,可以考虑禁用拷贝构造和赋值操作。(容器类型的类:存放数据元素的类,不知道这样理解对不对?没学过STL…)

template <typename T>
class List : public Object
{
protected:
	List(const List&);
	List& operator= (const List&);
public:
	List()
	{
	}
	//...
};

在这里插入图片描述
我们可以在List.h中添加拷贝构造和赋值操作符重载(protected属性),编译会报错,因为我们自己写了构造函数,所以编译器不会提供了!我们需要在public:后面加上List(){},这样就不会报错了!

我们可以在main函数里实验一下是否可以拷贝构造和赋值操作:

int main()
{
    DynamicList<int> L(5);

    DynamicList<int> n =L;

    return 0;
}

编译报错!
在这里插入图片描述
赋值呢?

int main()
{
    DynamicList<int> l(5);

    DynamicList<int> n(5);

    n = l;

    return 0;
}

还是报错!
在这里插入图片描述

3.2 下面代码正确嘛?

int main()
{
	StaticList<int,5> list;
	for(int i=0;i<list.capacity();i++)
	{
		list[i] = i*i;
	}
	return 0;
}

编译会报错,线性表必须先插入元素,才能使用操作符[ ]访问元素。

问题分析
在这里插入图片描述

4. 小结

  1. 顺序存储线性表的插入和删除操作存在重大效率隐患
  2. 线性表作为容器类,应该避免拷贝构造和拷贝赋值
  3. 顺序存储线性表可能被当成数组误用
  4. 工程开发中可以考虑使用数组类代替原生数组使用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值