文章目录
头文件:线性表的定义和包含的成员函数
#pragma once
typedef int ElemType;
const int DefaultCapacity = 5;
class SequenceTable {
private:
ElemType *data;
int length;
int capacity;
public:
//建立线性表
void CreateList(ElemType a[], int n);
//初始化线性表
void InitList();
//销毁线性表
void DestroyList();
//判断线性表是否为空
bool ListEmpty();
//求线性表的长度
int ListLength();
//输出线性表
void DispList();
//求线性表中某个数据元素的值,
bool GetElem(int, ElemType&);
//求某个元素的位置
int LocateElem(ElemType);
//插入数据
bool ListInsert(int, ElemType);
//删除数据
bool ListDelete(int, ElemType&);
//扩容
bool ListExpansion(int cap);
//缩容
bool ListShrinkage();
//批量添加
bool ListInsertAll(int ,ElemType*,int);
//批量删除
bool ListDeleteAll(int, int);
//获取当前容量
int ListCapacity();
};
部分函数实现逻辑
扩容ListExpansion(int )
扩容采用一个参数和原容量的1.5倍值进行比较,取较大值为扩容后的容量。开辟空间后将元素复制进去,并让
data
域指向新数组即可。
bool SequenceTable::ListExpansion(int cap)
{
int newCapacity = capacity*1.5;//扩大1.5倍
if (newCapacity < cap) newCapacity = cap;
ElemType* temp = new ElemType[newCapacity*sizeof(int)];
for (int i = 0; i < length; i++)
temp[i] = data[i];
data = temp;
capacity = newCapacity;
return true;
}
缩容ListShrinkage()
对需要缩容的线性表,采用缩小为原来的一半的策略。缩容过程与扩容过程基本相同,只是需要注意最后要更改当前容量
capacity
的值。
//缩容
bool SequenceTable::ListShrinkage()
{
if (capacity <= DefaultCapacity) return true;
int newCapacity = capacity >> 1;
if (newCapacity < DefaultCapacity) newCapacity = DefaultCapacity;
ElemType* temp = new ElemType[newCapacity];
for (int i = 0; i < length; i++)
temp[i] = data[i];
data = temp;
capacity = newCapacity;
return true;
}
有参构造函数CreateList(ElemType, int)
通过数组构造线性表,关于构造的过程都应该对容量进行控制,此处通过将传入的数组大小n与默认容量比较,取较大值,保证数组最低容量为
DefaultCapacity
。
void SequenceTable::CreateList(ElemType a[], int n)
{
if (n > DefaultCapacity) {
data = new ElemType[n];
capacity = n;
}
else {
data = new ElemType[DefaultCapacity];
capacity = DefaultCapacity;
}
for (int i = 0; i < n; i++)
data[i] = a[i];
length = n;
}
初始化函数InitList( )
使用默认容量,并对类中成员
capacity
和length
赋初值。
//初始化
void SequenceTable::InitList()
{
data = new ElemType[DefaultCapacity];
capacity = DefaultCapacity;
length = 0;
}
获取某个元素第一次出现的位置LocateElem(ElemType)
int SequenceTable::LocateElem(ElemType e)
{
for (int i = 0; i < length; i++) {
if (data[i] == e)
return i;
}
//如果不存在该元素,
return -1;
}
插入一个元素ListInsert(int , ElemType )
插入过程需要对插入位置下标进行检查,同时对容量进行检查,如果需要扩容,传入一个0使得默认扩容为1.5倍。元素插入的方法采用后移,结束后
length
需要加一。
bool SequenceTable::ListInsert(int position, ElemType e)
{
if (position < 0 || position >= length) {
cout << "插入过程下标越界" << endl;
return false;
}
if (length >= capacity)
ListExpansion(0);
for (int i = length; i > position; i--)
data[i] = data[i - 1];
data[position] = e;
++length;
return true;
}
删除一个元素ListDelete(int, ElemType&)
删除元素同插入元素一样,需要对下标进行检查,元素删除采用其之后元素前移的方式。删除后进行缩容判断并处理。
//position为待删除元素的下标,e为被删除的元素
bool SequenceTable::ListDelete(int position, ElemType&e)
{
if (position < 0 || position >= length)
return false;
e = data[position];
for (int i = position; i < length - 1; i++) {
data[i] = data[i + 1];
}
length--;
if (length * 2 < capacity)
ListShrinkage();
return true;
}
批量添加ListInsertAll(int, ElemType*,int )
需要对参数是否合法进行判断,对是否需要扩容进行判断。然后采用先将原来数组的
index
位置之后的元素(包括index
)后移n个位置,然后将array中的元素放进腾出的空间中。
bool SequenceTable::ListInsertAll(int index, ElemType*array,int n)
{
if (index < 0 || index >= length) return false;
if (n + length > capacity)
ListExpansion(n + length);
for (int i = length - 1; i >= index; i--) {
data[i + n] = data[i];
}
int i = 0;
while (i < n) {
data[index++] = array[i];
i++;
}
length += n;
return true;
}
//
批量删除ListDeleteAll(int , int )
对于参数做判断,并在删除元素后进行缩容判断。删除过程采用前移方式,将
end
(包括end
)之后的元素前移begin-end
个位置。
//删除[begin,end) 之间的所有元素
bool SequenceTable::ListDeleteAll(int begin, int end)
{
if(begin>=end||begin<0||end>length)
return false;
int n = end - begin;//待删除的元素个数
for (int i = begin; i < length; i++) {
data[i] = data[i + n];
}
length -= n;
//判断是否需要缩容
if (length * 2 < capacity)
ListShrinkage();
return true;
}
部分简单函数的实现
//销毁线性表
void SequenceTable::DestroyList()
{
delete[] data;
}
//判空
bool SequenceTable::ListEmpty()
{
return length==0;
}
//当前表中元素长度
int SequenceTable::ListLength()
{
return length;
}
//输出
void SequenceTable::DispList()
{
if (ListEmpty()) return;
for (int i = 0; i < length; i++)
cout << data[i] << " ";
cout << endl;
}
//获取某个位置的元素,将其通过e传出去
bool SequenceTable::GetElem(int position, ElemType& e)
{
if(position<0|| position>=length)
return false;
else {
e = data[position];
return true;
}
}