线性表的顺序表示:顺序表ADT_SeqList

本文介绍了线性表的顺序表示,即顺序表ADT_SeqList,讨论了其存储结构和逻辑特性。顺序表中逻辑相邻的元素在内存中相邻存储,通过地址计算可快速访问元素。文章提到了顺序表的主要操作,包括IsEmpty、Length、Find、Search、Insert、Delete、Update和Output,并指出该数据结构适用于C++的类、继承和模板类实现。顺序表的优点是存储空间利用率高,能快速随机访问,但频繁的插入和删除操作会导致效率降低,且需要合理管理内存避免浪费和溢出。

线性表的顺序表示是用一组地址连续的存储单元依次存储线性表中的元素。逻辑上相邻的元素在存储空间内页相邻。若已知顺序表中每个元素占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 T>
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 T>
class SeqList:public LinearList<T>
{
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 <class T>
SeqList<T>::SeqList(int mSize)
{
	maxLength = mSize;
	elements = new T[maxLength];
	n = 0;
}
template <class T>
bool SeqList<T>::IsEmpty() const
{
	return n == 0;
}
template <class T>
int SeqList<T>::Length() const
{
	return n;
}
template <class T>
bool SeqList<T>::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 <class T>
int SeqList<T>::Search(T x) const
{
	for(int i = 0; i < n; ++i)
		if(elements[i] == x) return i;
	return -1;
}
template <class T>
bool SeqList<T>::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 <class T>
bool SeqList<T>::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 <class T>
bool SeqList<T>::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 <class T>
void SeqList<T>::Output(ostream &out) const
{
	for(int i = 0; i < n; ++i)
		out << elements[i] << " ";
	out << endl;
}
template <class T>
void Union(SeqList<T> &A, SeqList<T> &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<int> 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;
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值