C++数据结构 数组加链表

#include<iostream>
using namespace std;

//对于线性表有必要执行的操作:
//创建,撤销
//确定线性表是否为空
//确定线性表的长度
//按索引查找一个元素
//按元素查找索引。
//按索引删除元素
//按索引插入元素
//从左到右的顺序输出线性表元素

//这是个老祖宗
template<class T>
class linearList
{
public:
	virtual ~linearList() {};
	virtual bool empty()const = 0;
	virtual int size()const = 0;
	virtual T& get(int theIndex)const = 0;
	virtual int indexOf(const T& theElement)const = 0;
	virtual void erase(int theIndex) = 0;
	virtual void insert(int theIndex, T& theElement) = 0;
	virtual void  Output(ostream out)const = 0;
};

//linearList的派生类arrayList(数组)(儿子1)
template <class T>
class arrayList :public linearList<T>
{
public :
	arrayList(int initialCapacity=10);//白手起家构造
	arrayList(const arrayList<T>& theList);//一切靠偷构造
	~arrayList() { delete[] element; }


	bool empty()const { return listSize == 0; }
	int size() const { return listSize; }
	int capacity()const { return arrayLength; }

	//这哥俩正好反过来
	T& get(int theIndex)const;
	int indexOf(const T& theElement)const;

	void erase(int theIndex);
	void insert(int theIndex, const T& theElement);
	
	void Output(ostream& out)const;
protected:
	//频繁用到的一个函数
	void checkIndex(int theIndex)const;//若索引无效,则抛出异常

	T* element;//那个数组
	int arrayLength;//一维数组的容量(底线)
	int listSize;//线性表的元素个数

	class iterator;//迭代器
	iterator begin() { return iterator(element); }
	iterator end() { return iterator(element + listSize); }
};

//构造函数
template<class T>
arrayList<T>::arrayList(int initialCapacity)
{
	if (initialCapacity < 1)
	{
		ostringstream s;//字符串输出流
		s << "initialCapacity =" << initialCapacity << "Must be >0";
		throw illegalParameterValue(s.str());
	}
	arrayLength = initialCapacity;
	element = new T[arrayLength];
	listSize = 0;
}

//拷贝构造
template<class T>
arrayList<T>::arrayList(const arrayList<T>& theList)
{
	arrayLength = theList.arrayLength;
	listSize = theList.listSze;
	element = new T[arrayLength];
	copy(theList.element, theList.elemnet + listSize, element);
	//copy函数的参数 你从哪,去何方,要复制到什么地方。
}

//函数括号后面加个const是想让本对象不要变动,就是找一找,看一看,返回个值,本体不要动

template<class T>
void arrayList<T>::checkIndex(int theIndex)const
{
	//确定没有跑到外太空:在0到listSize-1之间
	if (theIndex < 0 || theIndex >= listSize)//跑偏啦!!
	{
		ostringstream s;
		s << "index=" << theIndex << "size=" << listSize;
		throw illegalindex(s.str());
	}
}

template<class T>
T& arrayList<T>::get(int theIndex)const
{
	//返回索引为theIndex的元素
	//若此元素不存在,则抛出异常
	checkIndex(theIndex);

	return element[theIndex];//嗯,很简单~,这就是数组的优势呀,方便找
}

template<class T>
int arrayList<T>::indexOf(const T& theElement)const
{
    //返回元素theElement第一次出现时的索引
	//如果theElement不存在,则返回-1
	//查找元素theElement
	int theIndex = (int)(find(element, element + listSize, theElement) - element);
	if (theIndex == listSize)return -1;//莫得找到
	else return theIndex;
}

template<class T>
void arrayList<T>::erase(int theIndex)
{
	//删除表中索引为theIndex的元素,索引大于theIndex的元素其索引值减1
	//如果索引为theIndex元素不存在,则抛出异常,
	checkIndex(theIndex);
	//索引大于theIndex的元素向前(左)移动一个位置
	copy(element + theIndex + 1, element + listSize, element + theIndex);
	element[--listSize].~T();//这个在有些时候不可以写,(比如数组里面的东西是指针)所以这个我觉得最好不写
}

template<class T>
void arrayList<T> ::insert(int theIndex, const T& theElement)
{
	//在索引theIndex处插入元素theElement;
	//如果theIndex无效,则引发异常
	//这里没用那个判断函数是因为插入的话再listSize这个位置也行。
	if (theIndex<0 || theIndex>listSize)
	{
		ostringstream s;
		s << "index=" << theIndex << "size=" << listSize;
		throw illegalindex(s.str());
	}
	//这个灰常重要!!不能无限个添加呀
	//需要在加之前至少至少给人留一个空位。
	if (listSize == arrayLength)
	{
		//这个方法从哪来的????
		changeLength1D(element, arrayLength, 2 * arrayLength);
		arrayLength *= 2;
	}
	//索引大于等于theIndex的元素向后(右)移动一个位置
	copy_backward(element + theIndex, element + listSize, element + theIndex + 1);
	element[theIndex] = theElement;
	listSize++;
}

template<class T>
void arrayList<T>::Output(ostream& out)const
{
	//把线性表插入输出流
	copy(element, elemen + listSize, ostream_iterator<T>(cout, " "));
}

//重载<<
template<class T>
ostream& operator<<(ostream& out, const arrayList<T>& x)
{
	x.Output(out);
	return out;
}
//C++迭代器
//一个迭代器是一个指针,指向对象的一个元素
//一个迭代器可以用来逐个访问对象的所有元素
int main()
{
	int x[3] = { 0,1,2 };
	/*for (int i = 0; i != 3; i++)
	{
		cout << x[i] << " ";
	}*/
	//用指针y遍历数组x
	for (int* y = x; y != x + 3; y++)
	{
		cout << *y << " ";
	}
	cout << endl;

}
//arrayList的迭代器
//为arrayList定义一个双向迭代器iterator


template<class T>
class arrayList<T>::iterator {
public:
	typedef bidirectional_iterator_tag iterator_category;
	typedef T value_type;
	typedef	ptrdiff_t difference_type;
	typedef T* pointer;
	typedef T& reference;
	
	//构造函数
	iterator(T* thePosition = 0) {
		position = thePosition;
	}
	//解引用操作符
	T& operator*()const
	{
		return *position;
	}
	T* operator->()const
	{
		return &*position;
	}
	//迭代器的值增加
	iterator& operator++()//前++
	{
		++position;
		return *this;
	}
	iterator operator++(int) //后++
	{
		iterator old = *this;
		++position;
		return old;
	}
	//迭代器的值减少
	iterator& operator--()//前--
	{
		--position;
		return *this;
	}
	iterator operator--(int)//后--
	{
		iterator old = *this;
		--position;
		return old;
	}
	//测试是否相等
	bool operator!=(const iterator right)const
	{
		return position != right.position;
	}
	
protected:
	T* position;//指向表元素的指针

};



//----------------我是分割线--------------------------------------------
//以下是链表

//这是个节点
template<class T>
struct chainNode {
	//数据成员
	T element;
	chainNode<T>* next;
	//多个构造函数重载
	chainNode() {}
	chainNode(const T& element)
	{
		this->element = element;
	}
	chainNode(const T& element, const chainNode<T>* next)
	{
		this->element = element;
		this->next = next;
	}
};

//linearList的派生类chain(链表)(儿子2)
template<class T>
class chain :public linearList<T>
{
public:
	//构造,拷贝函数。析构函数
	chain(int initialCapacity = 10);
	chain(const chain<T>& c);
	~chain();

	//这里儿子必须得乖乖滴把父亲的纯虚函数实现(如果他想new对象的话)
	bool empty()const { return listSize == 0; }
	int size()const { return listSize; }
	void erase(int theIndex);
	void insert(int theIndex, const T& theElement);
	int indexOf(const T& theElement)const;
	T& get(int theIndex)const;
	void Output(ostream& out)const;

protected:
	void checkIndex(int theIndex)const;//若索引theIndex无效,则抛出异常

	chainNode <T>* firstNode;//老大哥,有了他就有一堆小弟,所以丢了他就啥都没得了
	int listSize;//老大哥+小弟的数目,需要时时手动更新(此案例头结点也存东西)

	class iterator;//迭代器
	iterator begin() { return iterator(firstNode); }
	iterator end() { return iterator(NULL); }
};

//构造函数
template<class T>
chain<T>::chain(int initialCapacity)
{
	if (initialCapacity < 1)
	{
		ostringstream s;
		s << "Initial capacity = " << initialCapacity << " Must be > 0";
		throw illegalParameterValue(s.str());
	}
	//所以。。。initialCapacity仿佛并没得什么用
	firstNode = NULL;
	listSize = 0;
}

//拷贝构造
template<class T>
chain<T>::chain(const chain<T>& theList)
{
	listSize = theList.listSize;

	//任何时候,要 . 出东西的时候都要小心!!!
	//链表theList为空
	if (listSize == 0)
	{
		firstNode = NULL;
		return;
	}
	//链表theList不为空
	chainNode<T>* sourceNode = theList.firstNode;//这是打入敌营的间谍
	firstNode = new chainNode<T>(sourceNode->element);//复制theList中的首元素
	sourceNode = sourceNode->next;
	chainNode<T>* targetNode = firstNode;//新老大的狗腿子(老大是不需要动的,只需要狗腿子帮忙就好了)

	while (sourceNode != NULL)
	{
		targetNode->next = new chainNode<T>(sourceNode->element);

		targetNode = targetNode->next;
		sourceNode = sourceNode->next;
	}
	targetNode->next = NULL;//狗腿子善后(狗腿子实惨)
}

//析构函数
template<class T>
chain<T>::~chain()
{
	while (firstNode)
	{
		chainNode<T>* next = firstNode->next;
		delete firstNode;
		firstNode = next;
	}
}

template<class T>
void chain<T>::checkIndex(int theIndex)const
{
	//确定没有跑到外太空:在0到listSize-1之间
	if (theIndex < 0 || theIndex >= listSize)//跑偏啦!!
	{
		ostringstream s;
		s << "index=" << theIndex << "size=" << listSize;
		throw illegalindex(s.str());
	}
}

template<class T>
T& chain<T>::get(int theIndex)const
{
	checkIndex(theIndex);

	//移动到所需要的的节点
	chainNode<T>* currentNode = firstNode;
	for (int i = 0; i < theIndex; i++)
	{
		currentNOde = currentNode->next;
	}
	return currentNode->element;
}
//返回元素theElement首次出现时的索引,如果theElement不存在,则返回-1
template<class T>
int chain<T>::indexOf(const T& theElement)const
{
	//查找元素
	chainNode<T>* currentNode = firstNode;
	int index = 0;
	while (currentNode->next != NULL && currentNode->element != theElement)
	{
		currentNode = currentNode->next;
		index++;
	}
	if (currentNode == NULL)return -1;
	return index;
}

//删除表中索引为theIndex的元素
template<class T>
void chain<T>::erase(int theIndex)
{
	chainNode<T>* deleteNode=firstNode;
	checkIndex(theIndex);
	if (theIndex == 0)
	{
		firstNode = firstNode->next;
	}
	else{
		chainNode<T>* p = firstNode;

		for (int i = 0; i < theIndex - 1; i++)
		{
			p = p->next;
		}
		deleteNode = p->next;
		p->next = p->next->next;//删除deleteNode指向的节点
	}
	listSize--;
	delete deleteNode;

}

//在索引theIndex出插入元素theElement;
template<class T>
void chain<T>::insert(int theIndex, const T& theElement)
{
	checkIndex(theIndex);
	chainNode<T>* currentNode = firstNode;
	if (theIndex == 0)
	{
		firstNode = new chainNode<T>(theElement, firstNode);
	}
	else {
		for (int i = 0; i < theIndex - 1; i++)
		{
			currentNode = currentNode->next;
		}
		currentNode->next = new chainNode<T>(theElement, currentNode->next);
	}
	listSize++;
}

//将链表元素送至输出流
template<class T>
void chain<T>::Output(ostream& out)const
{
	for (chainNode<T>* currentNode = firstNode; currentNode != NULL; current = current->next)
	{
		out << currentNode->element << " ";
	}
}

//重载<<
template <class T>
ostream& operator<<(ostream& out, const chain<T>& x)
{
	x.Output(out); return out;
}

template <class T>
class chain<T>::iterator
{
public:
	//C++的向前迭代器所需要的typedef语句省略
	//构造函数
	iterator(chainNode<T>* theNode = NULL)//这个NULL只是默认的
	{
		node = theNode;
	}

	//解引用操作符
	T& operator*()const { return node->element; }
	T* operator->()const { return &node->element; }
	//迭代器加法操作
	iterator& operator++()//前++
	{
		node = node->next;
		return *this;
	}
	iterator operator++(int)//后++
	{
		iterator old = *this;
		node = node->next;
		return old;
	}
    //测试是否相等
	bool operator!=(const iterator right)const
	{
		return node != right.node;
	}
	bool operator==(const iterator right)const
	{
		return node == right.node;
	}
protected:
	chainNode<T>* node;//指向表结点的指针
};

template<class T>
class extendedLinearList :linearList<T>
{
public:
	virtual ~extendedLinearList() {};
	virtual void clear()const = 0;
	//删除表中的所有元素;
	virtual push_back(const T& theElement) = 0;
	//在表尾插入元素theElement;
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值