二、编码实现

线性表类实现(class linearList、class chain)

template<typename 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;
	//返回元素theElement第一次出现时的索引
	virtual int indexOf(const T& theElement) const = 0;
	//删除索引为theIndex的元素
	virtual void earse(int theIndex) = 0;
	//把theElement插入线性表中索引为theIndex的位置上
	virtual void insert(int theIndex, const T& theElement) = 0;
	//把线性表插入输出流out
	virtual void output(ostream& out)const = 0;
};
template<typename T>
class chain:public linearList<T>
{
public:
	chain(int initialCapacity = 10);
	chain(const chain<T>& other);
	~chain();

	bool empty() const;
	int size() const;
	T& get(int theIndex)const override;
	int indexOf(const T& theElement)const override;
	void earse(int theIndex)override;
	void insert(int theIndex, const T& theElement)override;
	void output(ostream& out)const override;

private:
	void checkIndex(int theIndex)const;
private:
	chainNode<T>* firstNode;
	int listSize;
};

链表节点定义(struct chainNode)

template<typename T>
struct chainNode
{
	T element;
	chainNode<T> *next;

	chainNode() {}
	chainNode(const T& element) {
		this->element = element;
	}

	chainNode(const T& element,chainNode<T>* next) {
		this->element = element;
		this->next = next;
	}
};

构造函数、拷贝构造、析构函数

  • 复杂度:
    • 构造函数:Θ(1)
    • 拷贝构造:O(max{listSize,other.listSize})
    • 析构函数:O(listSize)
template<typename T>
chain<T>::chain(int initialCapacity = 10) 
{
	if (initialCapacity<=0) {
		ostringstream s;
		s << "Initial Capacity is " << initialCapacity << ",Must >=1";
		throw illegalParamterValue(s.str().c_str());
	}

	this->firstNode = nullptr;
	this->listSize = 0;
}

template<typename T>
chain<T>::chain(const chain<T>& other) 
{
	this->listSize = other.listSize;
	if (this->listSize == 0) {
		this->firstNode = nullptr;
		this->listSize = 0;
	}

	chainNode<T>* otherNode = other.firstNode;

	this->firstNode = new chainNode<T>(otherNode->element);
	chainNode<T>* tempNode= this->firstNode;

	while (otherNode->next)
	{
		tempNode->next = new chainNode<T>(otherNode->next->element);
		tempNode = tempNode->next;
		otherNode = otherNode->next;
	}
	tempNode->next = nullptr;
}

template<typename T>
chain<T>::~chain()
{
	chainNode<T> *temp = firstNode;
	while (temp) {
		firstNode = firstNode->next;
		delete temp;
		temp = firstNode;
	}

	/*方式二
	while (firstNode) {
		chainNode<T> *temp = firstNode->next;
		delete firstNode;
		firstNode = temp;
	}
	*/
}

checkIndex、empty、size函数 

template<typename T>
void chain<T>::checkIndex(int theIndex)const
{
	if((theIndex<0) || (theIndex>=listSize)){
		ostringstream s;
		s << "List size is " << listSize << ",theIndex is " << theIndex;
		throw illegalParamterValue(s.str().c_str());
	}
}
template<typename T>
bool chain<T>::empty() const
{
	return (listSize == 0);
}
template<typename T>
int chain<T>::size() const
{
	return listSize;
}

get函数

  • 必须通过指针遍历,所以时间复杂度:O(theIndex)
template<typename T>
T& chain<T>::get(int theIndex)const 
{
	checkIndex(theIndex);

	int index = 0;
	chainNode<T> *tempNode = firstNode;
	while (index != theIndex) {
		tempNode = tempNode->next;
		index++;
	}

	return tempNode->element;
}

indexOf函数

  •  必须通过指针遍历,所以时间复杂度:O(theIndex)
template<typename T>
int chain<T>::indexOf(const T& theElement) const
{
	chainNode<T> *tempNode = firstNode;
	for (int i = 0; i < listSize; ++i) {
		if (tempNode->element == theElement) {
			return i;
		}
		tempNode = tempNode->next;
	}
	return -1;

	/*方式二
	chainNode<T> *tempNode = firstNode;
	int index = 0;
	while ((tempNode != nullptr) &&(tempNode->element!= theElement)) {
		tempNode = tempNode->next;
		++index;
	}

	if (tempNode == nullptr) {
		return -1;
	}
	return index;
	*/
}

earse函数

  •  复杂度:O(theIndex)
template<typename T>
void chain<T>::earse(int theIndex)
{
	checkIndex(theIndex);

	chainNode<T> *deleteNode;
	
	//如果是头结点
	if (theIndex == 0) {
		deleteNode = firstNode;
		firstNode = firstNode->next;
	}
	else {
		int index = 0;
		chainNode<T> *tempNode = firstNode;

		while (index<theIndex - 1) {
			tempNode = tempNode->next;
		}
		deleteNode = tempNode->next;
		tempNode->next= tempNode->next->next;
	}

	delete deleteNode;
	deleteNode = nullptr;
	listSize--;
}

insert函数

  • 复杂度:O(theIndex) 
template<typename T>
void chain<T>::insert(int theIndex, const T& theElement)
{
	if ((theIndex<0) || (theIndex>listSize)) {
		ostringstream s;
		s << "List size is " << listSize << ",theIndex is " << theIndex;
		throw illegalParamterValue(s.str().c_str());
	}

	//如果是插入头结点
	if (theIndex == 0) {
		firstNode = new chainNode<T>(theElement,firstNode);
	}
	else {
		int index = 0;
		chainNode<T> *temptNode = firstNode;

		while (index < theIndex-1) {
			temptNode = temptNode->next;
			index++;
		}
		temptNode->next = new chainNode<T>(theElement, temptNode->next);
	}

	listSize++;
}

output函数、<<重载函数

  • 复杂度都是:O(listSize) 
  • <<重载函数是全局函数
template<typename T>
void chain<T>::output(ostream& out)const
{
	for (chainNode<T>* tempNode = firstNode; tempNode != nullptr; tempNode = tempNode->next) {
		out << tempNode->element << "  ";
	}
}
template<typename T>
ostream& operator<<(ostream& out,const chain<T>& x)
{
	x.output(out);
	return out;
}

演示案例

int main()
{
	chain<int> *myChain = new chain<int>();
	
	cout << "Current size is" << myChain->size() << endl;
	cout << "All number is ";
	myChain->output(cout);
	cout << endl << endl;

	cout << "Insert 1,2,3"<< endl;
	myChain->insert(0,1);
	myChain->insert(1, 2);
	myChain->insert(2, 3);

	cout << "Current size is" << myChain->size() << endl;
	cout << "All number is ";
	myChain->output(cout);
	cout << endl;
	cout << "Index 0 value is "<< myChain->get(0)<< endl;
	cout << "Index 1 value is " << myChain->get(1) << endl;
	cout << "Index 2 value is " << myChain->get(2) << endl;
	cout << "The index if value 1  is " << myChain->indexOf(1) << endl;
	cout << "The index if value 2  is " << myChain->indexOf(2) << endl;
	cout << "The index if value 3  is " << myChain->indexOf(3) << endl;
	cout << endl << endl;

	myChain->earse(1);
	cout << "earse 2"<< endl;
	cout << "Current size is" << myChain->size() << endl;
	cout << "All number is ";
	myChain->output(cout);
	cout << endl;
	cout << "Index 0 value is " << myChain->get(0) << endl;
	cout << "Index 1 value is " << myChain->get(1) << endl;
	cout << "The index if value 1  is " << myChain->indexOf(1) << endl;
	cout << "The index if value 3  is " << myChain->indexOf(3) << endl;
	cout << endl << endl;

	myChain->insert(1,2);
	cout << "Insert 2" << endl;
	cout << "Current size is" << myChain->size() << endl;
	cout << "All number is ";
	myChain->output(cout);
	cout << endl;
	cout << "Index 0 value is " << myChain->get(0) << endl;
	cout << "Index 1 value is " << myChain->get(1) << endl;
	cout << "Index 2 value is " << myChain->get(2) << endl;
	cout << "The index if value 1  is " << myChain->indexOf(1) << endl;
	cout << "The index if value 2  is " << myChain->indexOf(2) << endl;
	cout << "The index if value 3  is " << myChain->indexOf(3) << endl;

	return 0;
}

C++(数据结构与算法):10---线性表的实现(单链表形式)_单链表形式

三、迭代器设计
  • 在单链表中,使用指针next,我们只能从一个节点找到它的后继,但是不能访问其前驱节点。多以,下面的迭代器只重载了++运算符
template<typename T>
class chain:public linearList<T>
{
    /***/
public:
	class iterator {
	public:
		iterator(chainNode<T>* other=nullptr) {
			node = other;
		}
		/*iterator& operator=(const iterator<T>& other) {
			node = other.node;
			return *this;
		}*/

		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 other)const {
			return (node == other.node);
		}

		bool operator!=(const iterator other)const {
			return node != other.node;
		}
	protected:
		chainNode<T> *node;
	};

	iterator begin() {
		return iterator(firstNode);
	}
	iterator end() {
		return iterator(nullptr);
	}
    /***/
};

演示效果

int main()
{
	chain<int> *myChain = new chain<int>();
	
	cout << "Current size is" << myChain->size() << endl;
	cout << "All number is ";
	myChain->output(cout);
	cout << endl << endl;

	cout << "Insert 1,2,3"<< endl;
	myChain->insert(0,1);
	myChain->insert(1, 2);
	myChain->insert(2, 3);

	chain<int>::iterator iter = myChain->begin();
	for (; iter != myChain->end(); iter++) {
		cout << *iter<<"  ";
	}
	cout << endl;

	return 0;
}

C++(数据结构与算法):10---线性表的实现(单链表形式)_ide_02