线性表的特点
线性表的表现形式:
-零个或多个元素的组成的集合
-数据元素在位置上有序排列
-数据元素的数量有限且类型相同
-将元素插入线性表
线性表的分类:
只有前驱;只有后继;既有前驱,又有后继;
线性表的—些常用操作
-将元素从线性表中删除
-获取目标位置处元素的值
-设置目标位置处元素的值
-查找指定元素的位置
-获取线性表的长度
-清空线性表
线性表的注意事项:
-线性表虽然重载了[],但与数组使用不同的是,必须该位置有数据,才可以使用[],否则视为越界,扔异常
线性表抽象父类的实现
list.h:
#ifndef _List_H_
#define _List_H_
#include "CPlusPlus.h"
#include "Object.h"
namespace JYlib
{
template < typename T >
class List:public Object
{
protected:
List(const List& t);//不允许在类的外部拷贝构造或者赋值
List& operator =(const List& e);
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 find(const T& e)const =0;
virtual int length()const =0;
virtual void clear()=0;
};
}
#endif
SeqList(线性表的顺序存储与抽象实现)
SeqList特点:
-用一段连续的存储单元依次存储数据元素
-定义为抽象父类,完成基本的功能
-使用一维数组完成连续存储,存储空间的位置和大小由子类提供
![](https://i-blog.csdnimg.cn/blog_migrate/a4819e35461c3712b3f1aa6c9d2669c2.png)
顺序存储线性表的插入和删除操作的效率(耗时)取决于线性表存储数据元素类型。插入的数据结构越复杂,耗时越长。如插入字符串和整形差距很大
SeqList.h
#ifndef _SeqList_H_
#define _SeqList_H_
#include "List.h"
#include "Exception.h"
namespace JYlib
{
template < typename T >
class SeqList:public List<T>
{
protected:
T* m_array;
int m_length;
public:
bool insert(const T& e)
{
return this->insert(m_length,e);
}
bool insert(int i,const T& e)
{
bool ret = (0 <= i)&&(i <= m_length);//可以在尾部插入,所以是<=m_length
ret = ret &&((m_length + 1)<= capacity());
if(ret)
{
for(int j = m_length;j > i;j--)
{
m_array[j]=m_array[j-1];
}
m_array[i] = e;
m_length++;
}
return ret;
}
bool remove(int i)
{
bool ret = (0 <= i)&&(i < m_length);
if(ret)
{
for(int j = i;j < m_length;j++)
{
m_array[j]=m_array[j+1];
}
m_length--;
}
return ret;
}
bool set(int i,const T& e)const
{
bool ret = (0 <= i)&&(i < m_length);
if(ret)
{
m_array[i]=e;
}
return ret;
}
bool get(int i,T& e)const
{
bool ret = (0 <= i)&&(i < m_length);
if(ret)
{
e = m_array[i];
}
return ret;
}
int length()const
{
return m_length;
}
void clear()
{
m_length = 0;
}
int find(const T& e)const
{
int ret = -1;
for(int i =0;i<m_length;i++)
{
if(m_array[i] == e)
{
ret = i;
break;
}
}
return ret;
}
//返回引用,可以连续操作
T& operator[](int i)
{
if((0 <= i)&&(i < m_length))
{
return m_array[i];
}
else
{
THROW_EXCEPTION(IndexOutOfBoundsException,"Parameter i is invalid ...");
}
}
T operator[](int i)const
{
return (const_cast<SeqList<T>&>(*this))[i];
}
//纯虚函数实现抽象
virtual int capacity()const =0;
};
}//namespace JYlib
#endif
StaticList(静态顺序表)
StaticList特点 :使用原生数组作为顺序存储空间 使用模板参数决定数组大小
StaticList.h
#ifndef _StaticList_H_
#define _StaticList_H_
#include "SeqList.h"
namespace JYlib
{
template < typename T,int N >
class StaticList:public SeqList<T>//静态顺序存储表
{
protected:
T m_space[N];//定义静态顺序存储空间
public:
StaticList()
{
this->m_array = m_space;
this->m_length = 0;
}
int capacity()const//顺序存储空间容量
{
return N;
}
};
}//namespace JYlib
#endif
DynamicList(动态线性表)
DynamicList特点:
-申请连续堆空间作为顺序存储空间
-动态设置顺序存储空间的大小
-保证重置顺序存储空间时的异常安全性
函数异常安全保证 :如果抛出异常
★ 对象内的任何成员仍然能保持有效状态
★ 没有数据的破坏及资源泄漏
DynamicList.h
#ifndef _DynamicList_H_
#define _DynamicList_H_
#include "include/SeqList.h"
namespace JYlib
{
template < typename T >
class DynamicList:public SeqList<T>//动态顺序存储表
{
protected:
int m_capacity;//动态存储空间容量大小
public:
DynamicList(int capacity)
{
this->m_array = new T[capacity];
if(this->m_array != NULL)
{
this->m_capacity = capacity;
this->m_length = 0;
}
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* new_array = new T[capacity];
if(new_array != NULL)
{
int length = (m_capacity < capacity ? m_capacity : capacity);
for(int i=0;i<length;i++)
{
new_array[i] = this->m_array[i];//如果对象为类,重载了操作符[],可能发生异常
}
T* temp = this->m_array;//如果对象为类,会调用析构函数,可能发生异常
//确保实现完成,再写入,实现异常安全
this->m_length = length;
this->m_array = new_array;
m_capacity = capacity;
delete[] temp;//最后调用,有异常数据也正确保存了
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException,"No memory to resize DynamicList object ...");
}
}
}
~DynamicList()
{
delete[] this->m_array;
}
};
}//namespace JYlib
#endif