数据结构-线性表

数组实现线性表:

#include <iostream>
#include <sstream>
#include <string>
using namespace std;

//纯虚函数
//ADT抽象的过程
template <class T>
class LinearList
{
public:
	virtual ~LinearList(){};
	//为空,返回true
	virtual bool empty() const = 0;
	//返回线性表元素的个数
	virtual int size() const = 0;
	//查找:通过theIndex查找元素返回
	virtual T& get(int theIndex)const = 0;
	//查找:通过索引查找
	virtual int indexOf(const T& theElement)const = 0;
	virtual void DeleteElement(int theIndex) = 0;
	virtual void insertElement(int theIndex, const T& theElement) = 0;
	virtual void PrintList(ostream& out) const = 0;
	//线性表放到输出流中,重载<<
};

template <class T>
//继承的模板的类时候,注意类型名怎么写
class ArrayList:public LinearList<T>
{
public:
	//构造函数+析构函数
	ArrayList(int initialCapacity = 10);//缺省参数构造函数
	ArrayList(const ArrayList<T> &);
	~ArrayList(){ delete[] element; }
	//ADT 方法
	bool empty()const { return listSize == 0; };
	//返回线性表元素的个数
	int size() const{ return listSize; };
	//查找:通过theIndex查找元素返回
	 T& get(int theIndex)const;
	//查找:通过索引查找
	int indexOf(const T& theElement)const ;
	void DeleteElement(int theIndex);
	void insertElement(int theIndex, const T& theElement);
	void PrintList(ostream& out) const;

	//其他方法
	int Capacity()const{ return arrayLengh; }
	
protected:
	void checkIndex(int theIndex) const;
	T* element;		//存储线性表的数组
	int arrayLength;	//数组的容量
	int listSize;		//线性元素的个数

};
//线性表长度可以改变 -----动态数组
template <class T >
void ChangeLength(T*& a, int oldLength, int newLength)
{
	//新的长度有问题
	if (newLength < 0)
		throw 1;
	T* temp = new T[newLength];
	int number = oldLength>newLength ? oldLength : newLength;
	//初始位置,终止位置,目标
	copy(a, a + number, temp);//库函数
	delete[] a;	//释放老空间
	a = temp;
}
template <class T>
ArrayList<T>::ArrayList(int initialCapacity = 10)
{
	if (initialCapacity < 1)
	{
		throw 1;
	}
	arrayLength = initialCapacity;
	element = new T[arrayLength];
	listSize = 0;
}

template <class T>
ArrayList<T>::ArrayList(const ArrayList<T>& theList)
{
	arrayLength = theList.arrayLength;
	listSize = theList.ListSize;
	element = new T[arrayLength];
	copy(theList.element, theList.element + listSize, element);
}

template <class T>
void  ArrayList<T>::checkIndex(int theIndex) const
{	//索引从0开始到listSize-1(为数组保持一致)
	if (theIndex < 0 || theIndex >= listSize)
	{
		throw 1;
	}
}

//通过索引查找元素
template <class T>
T& ArrayList<T>::get(int theIndex)const
{
	try
	{
		checkIndex(theIndex);
	}
	catch (int)
	{
		cout << "索引不存在!" << endl;
	}
	return element[theIndex];
}

template <class T>
int ArrayList<T>::indexOf(const T& theElement)const
{
	//find没找到 返回-1;
	int theIndex = (int)(find(element, element + listSize, theElement) - element);
	if (theIndex == listSize)
	{
		return -1;
	}
	else
	{
		return theIndex;
	}
}
template<class T>
void ArrayList<T>::DeleteElement(int theIndex)
{
	try
	{
		checkIndex(theIndex);
		copy(element + theIndex + 1, element + listSize, element + theIndex);
		element[--listSize].~T();
	}
	catch (int)
	{
		cout << "索引无效。无法查找" << endl;
	}

}

template <typename T>
void  ArrayList<T>::insertElement(int theIndex, const T& theElement)
{
	if (theIndex<0 || theIndex>listSize)
	{
		throw 1;
	}
	//有效索引,判断数组是否满了
	if (listSize == arrayLength)
	{
		try
		{
			ChangeLength(element, arrayLength, 2 * arrayLength);
			arrayLength *= 2;
		}
		catch (int)
		{
			cout << "数组长度必须大于0" << endl;
		}
	}
	//把元素往右移动一个位置
	copy_backward(element + theIndex, element + listSize, element + listSize + 1);
	element[theIndex] = theElement;
	listSize++;//线性表大小+1
}

//线性表放到输出流中,重载<<
template <class T>
void ArrayList<T>::PrintList(ostream& out)const
{
	copy(element, element + listSize, ostream_iterator<T>(out, " "));
}
template <class T>
ostream& operator<<(ostream& out, const ArrayList<T>& x)
{
	x.PrintList(out);
	return out;
}

int main()
{
	ArrayList <char> z(4);
	try
	{
		z.insertElement(0, 'a');
		z.insertElement(1, 'b');
		z.insertElement(2, 'c');
		z.insertElement(3, 'd');
		z.insertElement(4, 'd');
		z.insertElement(5, 'd');
	}
	catch (int)
	{
		cout << "插索引错误" << endl;
	}
	ArrayList <int> t(4);
	try
	{
		t.insertElement(0, 1);
		t.insertElement(1, 2);
		t.insertElement(2, 3);
		t.insertElement(3, 4);
		t.insertElement(4, 5);
		t.insertElement(5, 6);
	}
	catch (int)
	{
		cout << "插索引错误" << endl;
	}
	t.DeleteElement(2);
	t.DeleteElement(7);
	cout << z << endl;
	cout << t << endl;
	return 0;
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
线性表是一种常见的数据结构,它表示具有相同数据类型的一组元素的有序序列。线性表中的元素之间存在一种顺序关系,每个元素都有一个前驱和一个后继(除了第一个元素没有前驱,最后一个元素没有后继)。线性表可以用顺序存储结构或链式存储结构实现。 在顺序存储结构中,线性表的元素按照顺序存储在连续的内存空间中,可以通过元素的下标来访问和操作元素。插入或删除元素时,需要移动其他元素,因此操作的时间复杂度较高。 链式存储结构中,线性表的每个元素都包含一个数据域和一个指针域,指针指向下一个元素。通过指针的链接,元素可以按照任意顺序存储在内存中,插入和删除操作只需要改变指针的指向,因此时间复杂度较低。 线性表常见的操作包括插入、删除、查找、获取长度等。其中插入和删除操作需要注意保持线性表的顺序关系。 常见的线性表有数组、链表、栈和队列。数组是最简单的线性表,通过下标可以直接访问元素;链表是动态存储结构,插入和删除操作方便,但访问元素需要遍历链表;栈是一种特殊的线性表,只允许在表的一端进行插入和删除操作;队列也是一种特殊的线性表,只允许在表的一端进行插入操作,在另一端进行删除操作。这些数据结构在实际应用中都有各自的应用场景和优缺点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值