线性表的顺序表示:顺序表ADT_SeqList
最后更新于:2022-04-01 20:51:08
线性表的顺序表示是用一组地址连续的存储单元依次存储线性表中的元素。逻辑上相邻的元素在存储空间内页相邻。若已知顺序表中每个元素占k个存
储单元第一个元素a[0]在计算机内存中的首地址是loc(a[0]),则表中一个元素a[i]在内存中的存储地址为loc(a[i]) = loc(a[0]) + i * k;
包含的函数:IsEmpty(), Length(), Find(), Search(), Insert(), Delete(), Update(), Output()。
此代码用于复习c++类,继承,模板类实现,函数作用已经在注释中。
优点:存储空间利用率高,可以随机存取元素。
缺点:遇到插入和删除操作频繁的应用时效率大大降低,分配空间时分配多了浪费,分配少了又要溢出。
实现代码:
~~~
#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
using namespace std;
template
class LinearList
{
public:
virtual bool IsEmpty() const = 0; // 为空则返回true
virtual int Length() const = 0; // 返回长度
virtual bool Find(int i, T &x) const = 0; // 若a[i]存在则x = a[i],返回true,不存在返回flase
virtual int Search(T x) const = 0; // 若存在等于x的元素则返回下标,否则返回-1
virtual bool Insert(int i, T x) = 0; // i == -1则x插在第一个元素之前, 否则x插在a[i]后,插入成功返回true
virtual bool Delete(int i) = 0; // 删除元素a[i],删除成功返回true
virtual bool Update(int i, T x) = 0; // 修改元素a[i]为x,若修改成功则返回true
virtual void Output(ostream &out) const = 0;
/* data */
protected:
int n;
};
template
class SeqList:public LinearList
{
public:
SeqList(int mSize);
~SeqList() {delete []elements;}
bool IsEmpty() const;
int Length() const;
bool Find(int i, T &x) const;
int Search(T x) const;
bool Insert(int i, T x);
bool Delete(int i);
bool Update(int i, T x);
void Output(ostream &out) const;
/* data */
private:
int maxLength, n;
T *elements;
};
template
SeqList::SeqList(int mSize)
{
maxLength = mSize;
elements = new T[maxLength];
n = 0;
}
template
bool SeqList::IsEmpty() const
{
return n == 0;
}
template
int SeqList::Length() const
{
return n;
}
template
bool SeqList::Find(int i, T &x) const
{
if(i < 0 || i > n - 1) { // i不合法
cout << "Out of Bounds" << endl;
return false;
}
x = elements[i];
return true;
}
template
int SeqList::Search(T x) const
{
for(int i = 0; i < n; ++i)
if(elements[i] == x) return i;
return -1;
}
template
bool SeqList::Insert(int i, T x)
{
if(i < -1 || i > n - 1) { // i不合法
cout << "Out of Bounds" << endl;
return false;
}
if(n == maxLength) { // 数组满了
cout << "OverFlow" << endl;
return false;
}
for(int j = n - 1; j > i; --j)
elements[j + 1] = elements[j];
elements[i + 1] = x;
n++;
return true;
}
template
bool SeqList::Delete(int i)
{
if(!n) { // 数组已经为空
cout << "UnderFlow" << endl;
return false;
}
if(i < 0 || i > n - 1) { // i不合法
cout << "Out of Bounds" << endl;
return false;
}
for(int j = i + 1; j < n; ++j)
elements[j - 1] = elements[j];
n--;
return true;
}
template
bool SeqList::Update(int i, T x)
{
if(i < 0 || i > n - 1) { // i不合法
cout << "Out of Bounds" << endl;
return false;
}
elements[i] = x;
return true;
}
template
void SeqList::Output(ostream &out) const
{
for(int i = 0; i < n; ++i)
out << elements[i] << " ";
out << endl;
}
template
void Union(SeqList &A, SeqList &B)
{
T x;
for(int i = 0; i < B.Length(); ++i) {
B.Find(i, x);
if(A.Search(x) == -1) A.Insert(A.Length() - 1, x);
}
}
int main(int argc, char const *argv[])
{
SeqList A(20), B(20);
for(int i = 0; i < 5; ++i)
A.Insert(i - 1, i); // A = {0, 1, 2, 3, 4}
cout << "顺序表A为:" << endl;
A.Output(cout);
for(int i = 5; i < 10; ++i)
B.Insert(i - 6, i); // B = {5, 6, 7, 8, 9}
cout << "顺序表B为:" << endl;
B.Output(cout);
A.Update(1, 5); // A = {0, 5, 2, 3, 4}
cout << "顺序表A为:" << endl;
A.Output(cout);
int flag = A.Search(2); // 元素中是否有2
if(flag != -1) cout << "有等于2的元素" << endl;
else cout << "无等于2的元素" << endl;
int x;
A.Find(2, x); // x = a[2];
cout << "a[2] == " << x << endl;
B.Insert(-1, 0); // B = {0, 5, 6, 7, 8, 9}
cout << "顺序表B为:" << endl;
B.Output(cout);
B.Insert(3, 2); // B = {0, 5, 6, 7, 2, 8, 9}
cout << "顺序表B为:" << endl;
B.Output(cout);
B.Delete(4); // B = {0, 5, 6, 7, 8, 9}
cout << "顺序表B为:" << endl;
B.Output(cout);
Union(A, B); // 合并A, B到A A = {0, 2, 3, 4, 5, 6, 7, 8, 9}
cout << "顺序表A为:" << endl;
A.Output(cout);
return 0;
}
~~~
';