【数据结构】线性表(数组实现)


1、线性表




2、线性表的抽象数据类型描述




3、线性表的数组描述


按照上述抽象描述,定义一个模板类来描述上述的抽象描述。


template<class T>
class LinearList
{
public:
	LinearList(int MaxListSize = 10);			//构造函数
	~LinearList()								//析构函数
	{
		delete []element;						//删除堆空间
	}
	
	bool isEmpty() const 						//判断线性表是否为空
	{
		return (length == 0);					
	}
	
	int Length() const 							//线性表长度
	{
		return length;
	}
	
	bool Find(int k, T& x) const;	    		//返回第k个元素到x中
	
	int Search(const T& x) const;				//返回x所在的位置
	
	LinearList<T>& Delete(int k, T& x); 		//删除第k个元素并将它返回到x中
	
	LinearList<T>& Insert(int k, const T& x); 	//在第k个元素之后的位置插入x
	
	void Output(ostream& out) const;			//输出线性表内容
	
private:
	int MaxSize;								//线性表可容纳最大长度
	int length;									//线性表中非空的长度		
	T *element;									//线性表数组头指针
};

下面依次分析各种操作。


3.1 Create()操作


Create()创建一个空线性表,对应的就是类的构造函数操作。构造函数里面首先要的就是对空间的分配,当然要确定类成员变量的值。

/*
构造函数
*/
template<class T>
LinearList<T>::LinearList(int MaxListSize)
{
	MaxSize = MaxListSize;
	element = new T[MaxSize];
	length = 0;
}

3.2 Destory()操作


Destory()操作主要就是对线性表对象分配的堆空间进行回收。

~LinearList()								//析构函数
	{
		delete []element;				        //删除堆空间
	}

3.3 isEmpty()操作

isEmpty()操作很简单,就是判断线性表是否为空。检查是否为空只需检查类length的值是否为零。

bool isEmpty() const 						//判断线性表是否为空
	{
		return (length == 0);					
	}

3.4 Length()操作


Length()操作就是要返回线性表的所含元素的个数。

int Length() const 							//线性表长度
	{
		return length;
	}

3.5 Find()操作


bool Find(int k, T& x) const;操作是将线性表中的第k个元素返回到x中,这里操作里面要注意的就是判断标号k是否是在线性表的范围内,若不在范围内,则返回false。

/*
返回第k个元素到x中
*/
template<class T>
bool LinearList<T>::Find(int k, T& x) const
{
	if(k > length || k < 0)
		return false;
	x = element[k];
	return true;
}

3.6 Search()


Search()函数就是查找传入的参数是否在线性表中,如果不在返回-1,如果在线性表中则返回该元素在线性表中的索引。

/*
遍历整个数组,发现被查找元素和数组中元素匹配则返回该元素位置
如果在数组中没有发现被查找元素,则返回-1
*/
template<class T>
int LinearList<T>::Search(const T& x) const
{
	for(int i=0; i<length; ++i)
	{
		if(x == element[i]) 
			return i;
	}
	return -1;
}

3.7 Delete()操作

Delete()操作要从线性表中删除一个元素,如果有该元素就删除,并返回到x;如果不存在该元素则抛出异常。要注意长度的变化。

/*
从线性表中删除一个元素
*/
template<class T>
LinearList<T>& LinearList<T>::Delete(int k, T& x)
{
	if(!Find(k, x)) 									//如果序列中没有该元素则抛出异常
	{
		throw "Out of Bounds";
	}
	//将第k个元素后的元素依次往前移动一个位置,覆盖掉第k个元素
	for(int i = k+1; i<length; ++i)
	{
		element[i-1] = element[i];
	}
	length -= 1;										//线性表长度减少一个长度
	return *this;
}

3.8 Insert()操作

Insert()是在索引k的后面插入一个元素,返回当前线性表;需要检查k是否在可插入的范围内。重要的是要检查当前线性表分配的空间是否已经存储满了。要注意长度的变化。

/*
在第k个元素的后面插入一个元素
*/
template<class T>
LinearList<T>& LinearList<T>::Insert(int k, const T& x)
{
	if(k > length || k < 0)
	{
		//抛出异常
		throw "插入元素位置不正确!";
	}
	if(length == MaxSize)
	{
		//抛出异常,空间不足
		throw "空间不足";
	}
	//将第k个元素后面的元素都往后移动一个单位
	for(int i=length; i>k; --i)
	{
		element[i] = element[i-1];
	}
	element[k] = x;
	length += 1;
	return *this;
}

3.9 Output()操作

为了使线性表数据可视化。

/*
输出线性表内容
*/
template<class T>
void LinearList<T>::Output(ostream& out) const
{
	out << endl <<"print list element: " << endl;
	for (int i = 0; i < length; i++)
	{
		out << element[i] << " ";
	}
	out << endl;
}

4、实现源码


tips:模板类的定义和实现要放在一个文件里面,不然会报错!!

.h文件

#ifndef __LINEARLIST_H__
#define __LINEARLIST_H__

#include <iostream>
using namespace std;


template<class T>
class LinearList
{
public:
	LinearList(int MaxListSize = 10);			//构造函数
	~LinearList()								//析构函数
	{
		delete []element;						//删除堆空间
	}
	
	bool isEmpty() const 						//判断线性表是否为空
	{
		return (length == 0);					
	}
	
	int Length() const 							//线性表长度
	{
		return length;
	}
	
	bool Find(int k, T& x) const;	    		//返回第k个元素到x中
	
	int Search(const T& x) const;				//返回x所在的位置
	
	LinearList<T>& Delete(int k, T& x); 		//删除第k个元素并将它返回到x中
	
	LinearList<T>& Insert(int k, const T& x); 	//在第k个元素之后的位置插入x
	
	void Output(ostream& out) const;			//输出线性表内容
	
private:
	int MaxSize;								//线性表可容纳最大长度
	int length;									//线性表中非空的长度		
	T *element;									//线性表数组头指针
};


/*
构造函数
*/
template<class T>
LinearList<T>::LinearList(int MaxListSize)
{
	MaxSize = MaxListSize;
	element = new T[MaxSize];
	length = 0;
}

/*
返回第k个元素到x中
*/
template<class T>
bool LinearList<T>::Find(int k, T& x) const
{
	if(k > length || k < 0)
		return false;
	x = element[k];
	return true;
}

/*
遍历整个数组,发现被查找元素和数组中元素匹配则返回该元素位置
如果在数组中没有发现被查找元素,则返回-1
*/
template<class T>
int LinearList<T>::Search(const T& x) const
{
	for(int i=0; i<length; ++i)
	{
		if(x == element[i]) 
			return i;
	}
	return -1;
}

/*
从线性表中删除一个元素
*/
template<class T>
LinearList<T>& LinearList<T>::Delete(int k, T& x)
{
	if(!Find(k, x)) 									//如果序列中没有该元素则抛出异常
	{
		throw "Out of Bounds";
	}
	//将第k个元素后的元素依次往前移动一个位置,覆盖掉第k个元素
	for(int i = k+1; i<length; ++i)
	{
		element[i-1] = element[i];
	}
	length -= 1;										//线性表长度减少一个长度
	return *this;
}


/*
在第k个元素的后面插入一个元素
*/
template<class T>
LinearList<T>& LinearList<T>::Insert(int k, const T& x)
{
	if(k > length || k < 0)
	{
		//抛出异常
		throw "插入元素位置不正确!";
	}
	if(length == MaxSize)
	{
		//抛出异常,空间不足
		throw "空间不足";
	}
	//将第k个元素后面的元素都往后移动一个单位
	for(int i=length; i>k; --i)
	{
		element[i] = element[i-1];
	}
	element[k] = x;
	length += 1;
	return *this;
}

/*
输出线性表内容
*/
template<class T>
void LinearList<T>::Output(ostream& out) const
{
	out << endl <<"print list element: " << endl;
	for (int i = 0; i < length; i++)
	{
		out << element[i] << " ";
	}
	out << endl;
}

/*
重载<<运算符
*/
template <class T>
ostream& operator<<(ostream& out, const LinearList<T>& x)
{
	x.Output(out);
	return out;
}


#endif // !__LINEARLIST_H__


.c文件

#include <iostream>
#include "LinearList.h"
using namespace std;


int main()
{
	LinearList<int> list(10);
	cout << "Length = " << list.Length() << endl;
	cout << "IsEmpty = " << list.isEmpty() << endl;
	list.Insert(0,2);
	list.Insert(1,6);
	list.Insert(2,8);
	list.Insert(0,4);
	list.Output(cout);
	int x;
	list.Delete(2,x);
	list.Output(cout);
	cout << "IsEmpty = " << list.isEmpty() << endl;
	return 0;
}



运行结果:








  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

空空的司马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值