重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
基于前面实现的数据结构类模板基础,继续完成基于顺序存储结构的线性表的实现,继承关系图如下:
涵江网站制作公司哪家好,找成都创新互联!从网页设计、网站建设、微信开发、APP开发、响应式网站设计等网站项目制作,到程序开发,运营维护。成都创新互联2013年开创至今到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选成都创新互联。
线性表是具有相同类型的n(>=)个数据元素的有限序列,(a0, a1, a2... an-1),其中ai是表项,n是表长度。
性质:
template
class List:public Object
{
protected:
List(const List&);
List& operator ==(const List&);
public:
List(){}
virtual bool insert(const T& e) = 0;
virtual bool insert(int i,const T& e) = 0;
virtual bool remove(int i) = 0;
virtual bool set(int i,const T& e) = 0;
virtual bool get(int i,T& e) const = 0;
virtual int length() const = 0;
virtual void clear() = 0;
};
线性表是数据元素的有序并且有限的集合,其中的数据元素类型相同,在程序中表现为一个特殊的数据结构,可以使用C++中的抽象类来表示,用来描述排队关系的问题。
定义:
线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表中的数据元素。
设计思路:
使用一维数组来实现存储结构:
// 存储空间:T* m_array; 当前长度:int m_length;
template
class SeqList : public List
{
protected:
T* m_array;
int m_length;
};
template
class SeqList : public List
{
protected:
T* m_array; // 顺序存储空间
int m_length; // 当前线性长度
public:
bool insert(int index, const T& e)
{
bool ret = ( (index>=0) && (index<=m_length) ); // <= 因为可以插入的点,必然比当前元素多1
if(ret && ( m_length < capacity() )) // 当前至少有一个空间可插入
{
for(int p=m_length-1; p>=index; p--)
{
m_array[p + 1] = m_array[p];
}
m_array[index] = e;
m_length++;
}
return ret;
}
bool insert(const T& e)
{
return insert(m_length, e);
}
bool remove(int index)
{
bool ret = ( (index>=0) && (index=0) && (index=0) && (index=0) && (index&>(*this)[index]; // 去除const属性,然后调用非const版本实现
}
// 顺序存储表的的容量
virtual int capacity() const = 0;
};
类模板
template < typename T, int N >
class StaticList : public SeqList
{
protected:
T m_space[]; // 顺序存储空间,N为模板参数
public:
StaticList(); // 指定父类成员的具体值
int capacity() const;
};
template < typename T, int N >
class StaticList : public SeqList
{
protected:
T m_space[N]; // 顺序存储空间,N为模板参数
public:
StaticList() // 指定父类成员的具体值
{
this->m_array = m_space;
this->m_length = 0;
}
int capacity() const
{
return N;
}
};
类模板
template < typename T>
class DynamicList : public SeqList
{
protected:
int capacity; // 顺序存储空间的大小
public:
DynamicList(int capacity); // 申请空间
int capacity(void) const // 返回capacity的值
// 重置存储空间的大小
void reset(int capacity);
~DynamicList(); // 归还空间
};
template
class DynamicList : public SeqList
{
protected:
int m_capacity;
public:
DynamicList(int capacity)
{
this->m_array = new T[capacity];
if(this->m_array != NULL)
{
this->m_length = 0;
this->m_capacity = capacity;
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException,"No memory to create DynamicList object ...");
}
}
int capacity()const
{
return m_capacity;
}
void resize(int capacity)
{
if(capacity != m_capacity)
{
T* array = new T[capacity];
if(array != NULL)
{
int length = (this->m_length < capacity ? this->m_length : capacity);
for(int i=0;im_array[i];
}
T* temp = this->m_array;
this->m_array = array;
this->m_length = length;
this->m_capacity = capacity;
delete[] temp;
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException,"No memory to create DynamicList object ...");
}
}
}
~DynamicList()
{
delete[] this->m_array;
}
};
顺序存储结构线性表的效率为O(n),主要受其插入和删除操作的影响(譬如插入操作时,要插入位置之后的数据要向后挪动) 。
两个长度相同的顺序存储结构线性表,插入、删除操作的耗时是否相同?
拷贝构造和赋值操作会导致两个指针指向同一个地址,导致内存重复释放。对于容器类型的类,可以考虑禁用拷贝构造和赋值操作。
原因: 1、对于生活中容器类的东西,我们无法对其进行赋值(譬如生活中我们不可能将杯子中的水进行复制,只能使用另一个杯子重新去获取等量的水)。
实现:将拷贝构造和赋值操作函数定义为proteced成员,在类的外部,不能使用。
protected:
List(const List&){}
List& operator = (const List&){}
线性表不能直接当做数组来使用
顺序存储结构线性表提供了数组操作符的重载,可以直接像数组一样,同过下标直接获取目标位置的元素,在具体的使用上类似数组,但是本质上不同,不能代替数组使用: