ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-03-05 20:31:01  阅读:119  来源: 互联网

标签:分析 insert const 线性表 int s2 s1 List 顺序存储


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. 工程开发中可以考虑使用数组类代替原生数组使用

标签:分析,insert,const,线性表,int,s2,s1,List,顺序存储
来源: https://blog.csdn.net/weixin_46258483/article/details/114378099

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有