版权声明:QQ:763905926 未经允许请勿转载,转载请注明出处! https://blog.csdn.net/lms1008611/article/details/81623415
线性表的顺序存储结构:指的是用一段地址连续的存储单元一次存储线性表中的数据元素,如下:
有了以上概念,我们可以使用一维数组来实现线性表的顺序存储结构,
存储空间:T* m_marry
当前长度:int m_length
整个类继承于之前我们写的List类,并采用泛型编程,在这里我们把顺序表分为静态顺序表与动态顺序表,静态顺序表的存储空间是直接在栈上分配的,通过类模板来定义空间长度;动态顺序表是在堆空间上申请存储空间。所以这里我们暂且生成一个顺序表父类SeqList,把顺序表的基本操作在SeqList里边实现,后边的静态顺序表StaticList与动态顺序表DynamicList均继承自SeqList。
#ifndef __SEQLIST_H__
#define __SEQLIST_H__
#include "ExcepTion.h"
#include "List.h"
namespace MyLib
{
template <typename T>
class SeqList : public List<T>
{
protected:
T* m_marray;
int m_length;
public:
bool insert(int index, const T& e) //插入操作
{
bool ret = true;
ret = (index >=0)&&(index <= m_length);
ret = ret && (m_length < capacity());
if (ret)
{
for ( int i=m_length-1; i>=index; i-- )
{
m_marray[i+1] = m_marray[i];
}
m_marray[index] = e;
m_length ++;
}
else
{
THROW_EXCEPTION(IndexOutOfBoundsException, "Out Of Bounts...");
}
return ret;
}
bool remove(int index) //移除操作
{
bool ret = true;
ret = (index >=0)&&(index < m_length);
if (ret)
{
for ( int i=index; i<m_length; i++ )
{
m_marray[i] = m_marray[i+1];
}
m_length--;
}
else
{
THROW_EXCEPTION(IndexOutOfBoundsException, "Out Of Bounts...");
}
return ret;
}
bool get(int index, T& e) //获取元素
{
bool ret = true;
ret = (index >=0)&&(index < m_length);
if (ret)
{
e = m_marray[index];
}
else
{
THROW_EXCEPTION(IndexOutOfBoundsException, "Out Of Bounts...");
}
}
bool set(int index, const T& e)const //设置元素
{
bool ret = true;
ret = (index >=0)&&(index < m_length);
if (ret)
{
m_marray[index] = e;
}
else
{
THROW_EXCEPTION(IndexOutOfBoundsException, "Out Of Bounts...");
}
}
int find(const T& e)
{
int ret = -1;
for (int i=0; i<m_length; i++)
{
if (e == m_array[i])
{
ret = i;
break;
}
}
return ret;
}
T& operator[](int index) //数组操作符重载
{
bool ret = true;
ret = (index >=0)&&(index < m_length);
if (ret)
{
return m_marray[index];
}
else
{
THROW_EXCEPTION(IndexOutOfBoundsException, "Out Of Bounts...");
}
}
int length()const //获取长度
{
return m_length;
}
void clear() //清除线性表
{
m_length = 0;
}
virtual int capacity() = 0;
};
}
#endif //__SEQLIST_H__
从SeqList类我们看到,除了将继承自List类的基本操作接口实现之外,我们还增加了一个纯虚函数 capacity(),所以SeqList类还bu能直接使用,这样做的目的就是为了区分静态顺序表StaticList与动态顺序表DynamicList,二者的存储结构空间一个在栈上一个在堆上。
下边先来看StaticList,它继承于SeqList
#ifndef __STATICLIST_H__
#define __STATICLIST_H__
#include "SeqList.h"
namespace MyLib
{
template <typename T, int N>
class StaticList : public SeqList<T>
{
private:
T marray[N]; //栈上定义一个数组,元素个数由类模板参数N确定
public:
StaticList()
{
m_marray = marray; //将顺序表的地址指向定义的数组
m_lenght = 0;
}
int capacity()
{
return N; //顺序表的容量同样等于类模板的参数N
}
};
}
#endif //__STATICLIST_H__
自此,一个完整的StatList就实现完成了,现在来实现DynamicList,
#ifndef __DYNAMICLIST_H__
#define __DYNAMICLIST_H__
#include "SeqList.h"
namespace MyLib
{
template <typename T>
class DynamicList : public SeqList<T>
{
private:
int m_capacity;
public:
DynamicList(int capacity)
{
m_marray = new T[capacity];
if (NULL != m_marray)
{
m_capacity = capacity;
m_length = 0;
}
else
{
THROW_EXCEPTION(NoEnoughtMemoryException, "No Enough Memory To Create DynamicList object...");
}
}
int capacity()
{
return m_capacity;
}
void resize(int capacity) //重置线性表空间大小
{
if (capacity != m_capacity)
{
int length = (m_length < capacity? m_length : capacity);
T *array = new T[length];
if (NULL != array)
{
for (int i=0; i<length; i++)
{
array[i] = m_marray[i];
}
T* temp = m_marray;
m_marray = array;
m_length = length;
m_capacity = capacity;
delete[] temp;
}
else
{
THROW_EXCEPTION(NoEnoughtMemoryException, "No Enough Memory To Resize DynamicList object...")
}
}
}
~DynamicList()
{
if (NULL != m_marray)
{
delete[] m_marray;
}
}
};
}
#endif //__DYNAMICLIST_H__
这样,我们将StaticList与DynamicList都 实现完了,现在我们在main函数中使用一下
#include <iostream>
#include <string>
#include "ExcepTion.h"
#include "StaticList.h"
#include "DynamicList.h"
using namespace std;
using namespace MyLib;
int main()
{
StaticList<int, 5> list1; //使用StaticList线性表
for (int i=0; i<list1.capacity(); i++)
{
list1.insert(i, i);
}
for (int i=0; i<list1.length(); i++)
{
cout << list1[i] << endl;
}
cout << "******************************" << endl;
DynamicList<int> list2(10); //使用DynamicList线性表
for (int i=0; i<list2.capacity(); i++)
{
list2.insert(i, i);
}
list2.resize(8); //重置顺序表空间
for (int i=0; i<list2.length(); i++)
{
cout << list2[i] << endl;
}
system("pause");
return 0;
}
编译输出:
更多的测试可以自行验证