在数据结构实战开发中类继承关系图中总体概括了数据结构实战开发中所有类的继承关系,本文分析线性表中顺序表的实现,下一篇实现包括静态顺序表StaticList和动态顺序表DynamicList。
线性表的顺序存储结构
顺序存储的定义:线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表中的数据元素。
List实现
既然是线性表,那么首先需要线性表抽象类List,主要是一些对线性表的操作:
#ifndef _LIST_H_
#define _LIST_H_
#include "Object.h"
namespace DTLib
{
// 对于容器类型的类,可以考虑禁用拷贝构造和赋值操作
template <typename T>
class List : public Object
{
private:
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 find(const T& e) const = 0;
virtual int length() const = 0;
virtual void clear() = 0;
};
}
#endif
SeqList实现
其次要实现SeqList,实现要点:
(1)抽象类模板 , 存储空间的位置和大小由子类完成;
(2)实现顺序存储结构线性表的关键操作(增、删、改、查等);
(3)提供数组操作符,方便快速获取元素。
#ifndef _SEQLIST_H_
#define _SEQLIST_H_
#include "List.h"
#include "Exception.h"
namespace DTLib
{
template < typename T >
class SeqList : public List<T>
{
protected:
T* m_array; // 顺序存储空间
int m_length; // 当前线性表长度
public:
// 重写父类List的成员函数
bool insert(int i, const T& e)
{
bool ret = ((0 <= i) && (i <= m_length));
ret = ret && (m_length < capacity());
if (ret)
{
for (int p = m_length - 1; p >= i; p--)
{
m_array[p + 1] = m_array[p];
}
m_array[i] = e;
m_length++;
}
return ret;
}
bool insert(const T& e)
{
return insert(m_length, e);
}
bool remove(int i)
{
bool ret = ((0 <= i) && (i < m_length));
if (ret)
{
for (int p = i; p < m_length - 1; p++)
{
m_array[p] = m_array[p + 1];
}
m_length--;
}
return ret;
}
bool set(int i, const T& e)
{
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 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;
}
int length() const
{
return m_length;
}
void clear()
{
m_length = 0;
}
// 顺序存储线性表的数组访问方式
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;
};
}
#endif