#include
using namespace std;
#define InitSize 10 //动态数组的初始化尺寸
#define IncSize 5 //当动态数组存满数据后每次扩容的元素个数
/*
//静态数组来保存顺序表中的元素
typedef struct
{
int m_data[10];//10个位置
int m_length;//顺序表中当前实际长度,当前顺序表中存储的元素个数
}SeqList01;
//动态数组来保存顺序表中的元素
typedef struct
{
int *m_pData;//顺序表中的元素保存在m_pData指向的内存空间中
int m_length;//顺序表中存储元素的实际长度
int m_maxSize;//动态数组的最大容量,动态数组可以扩容,记录该值
}SeqList02;
*/
template //T表示数组中的元素类型
class SeqList
{
public:
SeqList(int length=InitSize);//构造函数,参数可以有默认值
~SeqList();//析构函数
public:
bool ListInsert(int i, const T&e);//在第i个位置插入指定元素e
bool ListDelete(int i);//删除第i个位置的元素
bool GetElement(int i, T&e);//获取第i个元素的值
int LocateElement(const T&e);//按照元素值查找其在顺序表中出现的位置
void DisaplayList();//输出线性表中的所有数据
int GetListLength();//获取线性表的长度
void ReverseList();//翻转线性表
void TraverseList();//遍历数组中的元素,并输出
private:
void IncreaseSize();//当顺序表存储数据满,调用次函数为书虚表扩容。
private:
T *m_pData;//顺序表中的元素保存在m_pData指向的内存空间中
int m_length;//顺序表中存储元素的实际长度
int m_maxSize;//动态数组的最大容量,动态数组可以扩容,记录该值
};
//在外面进行函数的定义
template
SeqList::SeqList(int length)
{
m_pData = new T[length];//为一维数组动态分配内存
m_length = 0; //顺序表当前长度为0,表示还没存入任何数据元素
m_maxSize = length; //当前最多可以存入的数据的个数m_maxSize
}
//通过析构函数来对线性表进行资源释放
template
SeqList::~SeqList()
{
delete[]m_pData;
//将数组中的元素个数归为0;
m_length = 0;
}
/*
在第i个位置后面插入元素e,时间复杂度为O(n),时间开销主要源于元素的移动。
如插入位置为3的位置,则3后面的元素都需要移动。
注意:数组的下标从0开始,位置从1开始编号。所以下标和位置的对应关系是
位置-1==数组编号
*/
template
bool SeqList::ListInsert(int i, const T&e)
{
//如果顺序表的元素已经满,那么插入数据失败
if (m_length >= m_maxSize)
{
//cout << "顺序表中的元素已经满了,插入失败" << endl;
//return false;
//扩容
IncreaseSize();
}
//判断插入数据的位置i是否合法,i的合法值应该从1到m_length+1之间
if ((i < 1) || (i > (m_length + 1)))
{
cout << "插入数据的位置不合法,请重新检查插入位置" << m_length + 1 << endl;
return false;
}
/*
从最后一个元素向前面遍历,到插入新元素的第i个位置,分别将这些位置中元素向后移动。
如向位置为2的位置插入一个元素,那么就是插入到数组中编号为1的位置,
向位置为i的位置插入一个元素,那么就是插入到数组中编号为i-1的位置,
如数组长度为5,向第2个位置插入数据,则需要将数组标号为1的元素向后依次移动。
分析时间复杂度为(1+2+3+4+....(n-1)+n)/(n+1)= n/2
*/
for (int j = m_length; j >= i; j--)
{
m_pData[j] = m_pData[j-1];
}
//在位置为i的位置插入元素,因为数组下标从0开始,所以存储在数组中的位置是i-1
m_pData[i-1] = e;
cout << "成功在位置为i==" << i << "的位置插入元素" << e << endl;
//将数组中的存储元素的个数增加1
m_length++;
cout << "当前数组中元素的个数"< endl;
return true;
}
/*
删除第i个位置的元素,则后面的元素需要一次前移动
*/
template
bool SeqList::ListDelete(int i)
{
//判断线性表是否为空,如果元素的个数为空,则提示不能删除
if (m_length < 1)
{
cout << "线性表为空,删除失败" << endl;
return false;
}
//判断删除元素的位置是否合法,i<1或者i>m_length,则不合法
if ((i < 1) || (i > m_length))
{
cout << "删除的位置" << i << "不合法" << "删除的元素应该在" << i << "到" << m_length << "之间" << endl;
return false;
}
cout << "删除元素i==" << i << "位置元素" << m_pData[i - 1] << "成功" << endl;
//执行删除元素的代码,删除i位置,则存储在数组中是i-1,则后面的元素都需要向前面移动
for (int j = i; j < m_length; j++)
{
m_pData[j - 1] = m_pData[j];
}
//拷贝完毕,最后一个位置的元素应该删除,否则最后一个元素数值不为0
m_pData[m_length - 1] = 0;
m_length--;
//注意这里的元素已经删除,输出的是删除元素之后的下一个元素
//cout << "删除元素i==" << i << "位置元素" << m_pData[i - 1] << "成功" << endl;
cout << "删除元素i==" << i << "位置元素成功" << endl;
return true;
}
//获取第i个位置的元素值,并使用e返回
template
bool SeqList::GetElement(int i, T & e)
{
//判断数组的长度
if (m_length < 1)
{
cout << "线性表的长度为0,不能获取元素" << endl;
return false;
}
//判断获取的位置是否合法
if ((i < 1) || i > m_length)
{
cout << "获取的位置不合法" << endl;
return false;
}
e = m_pData[i - 1];//第i个位置保存在数组中位置为i-1
cout << "成功获取位置为i==" << i <<"的元素"<< endl;
return true;
}
//按照元素值查找其在顺序表中出现的位置
template
int SeqList::LocateElement(const T&e)
{
for (int k = 0; k < m_length; k++)
{
if (e == m_pData[k])
{
//e = m_pData[k];
cout << "线性表中存在元素值为" << e << "的元素" << endl;
return k+1;//k为数组中的存储位置,返回值应该加1,表示是第几个元素
}
}
cout << "线性表中不存在元素值为" << e << "的元素" << endl;
return 0;
}
//遍历输出
template
void SeqList::DisaplayList()
{
TraverseList();
}
//获取线性表的长度
template
int SeqList::GetListLength()
{
return m_length;
}
//反转线性表,
template
void SeqList::ReverseList()
{
//翻转数组中的元素 编号为i的位置和编号为数组总编号-i的位置进行交换(m_length-1数组最高的位置的编号)
T tep;
for (int i = 0; i < m_length/2; i++)//这里如果没有 /2,会交换两次==等价于没交换
{
tep = m_pData[i];
m_pData[i] = m_pData[m_length - 1 - i];
m_pData[m_length - 1 - i] = tep;
}
}
//数组元素的遍历输出
template
void SeqList::TraverseList()
{
for (int k = 0; k < m_length; k++)
{
cout << m_pData[k] << endl;
}
}
template
void SeqList::IncreaseSize()
{
T *p = m_pData;
m_pData = new T[m_maxSize + IncSize];//重新为线性表分配更大的内存空间
for (int i = 0; i < m_length; i++)
{
//把数据搬移过去
m_pData[i] = p[i];
}
//设置最大存储数据的数量
m_maxSize = m_maxSize + IncSize;
//释放原来的内存空间
delete[]p;
}
int main()
{
SeqList<int>* seqList = new SeqList<int>(10);
//注意插入空线性表只能从第一个位置开始插入,否则会报错
seqList->ListInsert(1, 1111);
seqList->ListInsert(2, 2222);
seqList->ListInsert(3, 3333);
seqList->ListInsert(4, 4444);
seqList->TraverseList();
seqList->ListDelete(2);
seqList->TraverseList();
//测试获取元素的位置
int value = 0;
seqList->GetElement(3, value);
cout << "value=="< endl;
//查找线性表中是否包含e元素,并将值返回
int number01= seqList->LocateElement(3333);
cout << "number01==" << number01 << endl;
//翻转数组
cout << "-----------------------------" << endl;
seqList->TraverseList();
cout << "*****************************" << endl;
seqList->ReverseList();
seqList->TraverseList();
cout << "扩容*****************************" << endl;
//测试扩容函数
for (int i = 1; i < 30; i++)
{
seqList->ListInsert(i, i * 3);
}
seqList->TraverseList();
std::cout << "Hello World!\n";
return 0;
}
/*
2021年11月8日21点28分
*/