顺序表头文件 sq_list.h
#ifndef __SQ_LIST_H__
#define __SQ_LIST_H__
#ifndef DEFAULT_SIZE
#define DEFAULT_SIZE 1000 // 缺省元素个数
#endif
// 顺序表类模板
template <class ElemType>
class SqList
{
protected:
// 数据成员:
ElemType* elems; // 元素存储空间
int maxSize; // 顺序表最大元素个数
int count; // 元素个数
public:
// 抽象数据类型方法声明及重载编译系统默认方法声明:
SqList(int size = DEFAULT_SIZE); // 构造函数模板
virtual ~SqList(); // 析构函数模板
int Length() const; // 求线性表长度
bool Empty() const; // 判断线性表是否为空
void Clear(); // 将线性表清空
void Traverse(void (*visit)(const ElemType&)) const; // 遍历线性表
bool GetElem(int position, ElemType& e) const; // 求指定位置的元素
bool SetElem(int position, const ElemType& e); // 设置指定位置的元素值
bool Delete(int position, ElemType& e); // 删除元素
bool Delete(int position); // 删除元素
bool Insert(int position, const ElemType& e); // 插入元素
SqList(const SqList<ElemType>& source); // 复制构造函数模板
SqList<ElemType>& operator =(const SqList<ElemType>& source); // 重载赋值运算符
};
// 顺序表类模板的实现部分
template <class ElemType>
SqList<ElemType>::SqList(int size)
// 操作结果:构造一个最大元素个数为size的空顺序表
{
maxSize = size; // 最大元素个数
elems = new ElemType[maxSize]; // 分配存储空间
count = 0; // 空线性表元素个数为0
}
template <class ElemType>
SqList<ElemType>::~SqList()
// 操作结果:销毁线性表
{
delete[] elems; // 释放存储空间
}
template <class ElemType>
int SqList<ElemType>::Length() const
// 操作结果:返回线性表元素个数
{
return count; // 返回元素个数
}
template <class ElemType>
bool SqList<ElemType>::Empty() const
// 操作结果:如线性表为空,则返回true,否则返回false
{
return count == 0; // count == 0表示线性表为空
}
template <class ElemType>
void SqList<ElemType>::Clear()
// 操作结果:清空线性表
{
count = 0; // 空线性表元素个数为0
}
template <class ElemType>
void SqList<ElemType>::Traverse(void (*visit)(const ElemType&)) const
// 操作结果:依次对线性表的每个元素调用函数(*visit)
{
for (int temPos = 1; temPos <= Length(); temPos++)
{ // 对线性表的每个元素调用函数(*visit)
(*visit)(elems[temPos - 1]);
}
}
template <class ElemType>
bool SqList<ElemType>::GetElem(int position, ElemType& e) const
// 操作结果:当线性表存在第position个元素时,用e返回其值,返回true, 否则返回false
{
if (position < 1 || position > Length())
{ // position范围错
return false; // 元素不存在
}
else
{ // position合法
e = elems[position - 1];
return true; // 元素存在
}
}
template <class ElemType>
bool SqList<ElemType>::SetElem(int position, const ElemType& e)
// 操作结果:将线性表的第position个元素赋值为e,
// position的取值范围为1≤position≤Length(),
// position合法时返回true,否则返回false
{
if (position < 1 || position > Length())
{ // position范围错
return false; // 范围错
}
else
{ // position合法
elems[position - 1] = e;
return true; // 成功
}
}
template <class ElemType>
bool SqList<ElemType>::Delete(int position, ElemType& e)
// 操作结果:删除线性表的第position个元素, 并前用e返回其值,
// position的取值范围为1≤position≤Length(),
// position合法时返回true,否则返回false
{
if (position < 1 || position > Length())
{ // position范围错
return false; // 范围错
}
else
{ // position合法
GetElem(position, e); // 用e返回被删除元素的值
ElemType temElem; // 临时元素
for (int temPos = position + 1; temPos <= Length(); temPos++)
{ // 被删除元素之后的元素依次左移
GetElem(temPos, temElem); SetElem(temPos - 1, temElem);
}
count--; // 删除后元素个数将自减1
return true; // 删除成功
}
}
template <class ElemType>
bool SqList<ElemType>::Delete(int position)
// 操作结果:删除线性表的第position个元素,
// position的取值范围为1≤position≤Length(),
// position合法时返回true,否则返回false
{
if (position < 1 || position > Length())
{ // position范围错
return false; // 范围错
}
else
{ // position合法
ElemType temElem; // 临时元素
for (int temPos = position + 1; temPos <= Length(); temPos++)
{ // 被删除元素之后的元素依次左移
GetElem(temPos, temElem); SetElem(temPos - 1, temElem);
}
count--; // 删除后元素个数将自减1
return true; // 删除成功
}
}
template <class ElemType>
bool SqList<ElemType>::Insert(int position, const ElemType& e)
// 操作结果:在线性表的第position个元素前插入元素e,
// position的的取值范围为1≤position≤Length()+1
// 如线性表已满,则返回false,
// 如position合法, 则返回true, 否则返回false
{
if (count == maxSize)
{ // 线性表已满返回false
return false;
}
else if (position < 1 || position > Length() + 1)
{ // position范围错
return false; // 范围错
}
else
{ // 成功
ElemType temElem; // 临时元素
for (int temPos = Length(); temPos >= position; temPos--)
{ // 插入位置之后的元素右移
GetElem(temPos, temElem); SetElem(temPos + 1, temElem);
}
count++; // 插入后元素个数将自增1
SetElem(position, e); // 将e赋值到position位置处
return true; // 插入成功
}
}
template <class ElemType>
SqList<ElemType>::SqList(const SqList<ElemType>& source)
// 操作结果:由线性表source构造新线性表——复制构造函数模板
{
maxSize = source.maxSize; // 最大元素个数
count = source.count; // 线性表元素个数
elems = new ElemType[maxSize]; // 分配存储空间
for (int temPos = 1; temPos <= source.Length(); temPos++)
{ // 复制数据元素
elems[temPos - 1] = source.elems[temPos - 1]; // 复制元素值
}
}
template <class ElemType>
SqList<ElemType>& SqList<ElemType>::operator =(const SqList<ElemType>& source)
// 操作结果:将线性表source赋值给当前线性表——重载赋值运算符
{
if (&source != this)
{
maxSize = source.maxSize; // 最大元素个数
count = source.count; // 线性表元素个数
delete[]elems; // 释放存储空间
elems = new ElemType[maxSize]; // 分配存储空间
for (int temPos = 1; temPos <= source.Length(); temPos++)
{ // 复制数据元素
elems[temPos - 1] = source.elems[temPos - 1]; // 复制元素值
}
}
return *this;
}
#endif
测试程序:
#include <iostream> // 编译预处理命令
using namespace std; // 使用命名空间std
#include "sq_list.h" // 顺序表类
template <class ElemType>
void Show(const ElemType& e)
// 操作结果: 显示数据元素
{
cout << e << " ";
}
int main()
{
char select = '0';
SqList<double> la, lb;
double e;
int position;
while (select != '7')
{
cout << endl << "1. 生成线性表.";
cout << endl << "2. 显示线性表.";
cout << endl << "3. 检索元素.";
cout << endl << "4. 设置元素值.";
cout << endl << "5. 删除元素.";
cout << endl << "6. 插入元素.";
cout << endl << "7. 退出";
cout << endl << "选择功能(1~7):";
cin >> select;
switch (select)
{
case '1':
cout << endl << "输入e(e = 0时退出):";
cin >> e;
while (e != 0)
{
la.Insert(la.Length() + 1, e);
cin >> e;
}
break;
case '2':
lb = la;
lb.Traverse(Show<double>);
break;
case '3':
cout << endl << "输入元素位置:";
cin >> position;
if (!la.GetElem(position, e))
cout << "元素不存储." << endl;
else
cout << "元素:" << e << endl;
break;
case '4':
cout << endl << "输入位置:";
cin >> position;
cout << endl << "输入元素值:";
cin >> e;
if (!la.SetElem(position, e))
cout << "位置范围错." << endl;
else
cout << "设置成功." << endl;
break;
case '5':
cout << endl << "输入位置:";
cin >> position;
if (!la.Delete(position, e) && !la.Delete(position))
cout << "位置范围错." << endl;
else
cout << "被删除元素值:" << e << endl;
break;
case '6':
cout << endl << "输入位置:";
cin >> position;
cout << endl << "输入元素值:";
cin >> e;
if (!la.Insert(position, e))
cout << "位置范围错." << endl;
else
cout << "成功。" << e << endl;
break;
}
}
return 0; // 返回值0, 返回操作系统
}
例程均来自清华大学出版社 《数据结构与算法》(C++版)作者:唐宁九 游洪跃。主要学习模板(模板类、模板函数)在这里的使用,如果原理知识还不懂,可以找本数据结构的数看看,不管是用C、C++还是java实现的,数据结构的原理是通用的,只是呈现形式不同。