一、链表实现
  • 若用链表实现,我们将考虑使用链表的左端还是右端来作为栈顶
    • 如果使用链表右端作为栈顶,那么栈操作top、push、pop的实现需要调用链表方法get(size()-1)、insert(size(),theElement)和rease(size()-1)。每一个链表方法需要用时O(size())
    • 如果使用链表左端作为栈顶,那么栈操作调用链表方法get(0)、insert(0,theElement)和rease(0),其中每一个链表方法需要用时Θ(1)
  • 因此我们选择链表的左端作为栈顶
二、继承于chain类与stack类实现
  • 前面用链表使用线性表的时候,我们使用到chain类,此处我们将定义一个类derivedLinkedStack继承于chain与stack来实现栈的链表形式

代码实现

  • 我们在derivedLinkedStack类内直接调用基类chain的方法实现栈的操作,这样大大简化了程序的设置,derivedLinkedStack类的每一种方法(包括构造函数和push方法)的时间复杂度都是Θ(1)

头文件定义

#include <stdio.h>
#include <stdlib.h>
#include <sstream>
#include <iostream>
#include <string>
#include <algorithm>
#include <numeric>
#include <iterator>

using std::cout;
using std::endl;
using std::string;

异常类定义

class illegalParameterValue
{
	string message;
public:
	illegalParameterValue(const char *theMessage = "Illegal Parameter Value") :message(theMessage) {}
	const char *what() {
		return message.c_str();
	}
};

class stackEmpty
{
public:
	stackEmpty(string theMessage ="Invalid operation on empty stack")
	{
		message = theMessage;
	}
	const char *what() {
		return message.c_str();
	}
private:
	string message;
};

linearList、stack抽象类的定义

template<typename T>

class linearList
{
public:
	virtual ~linearList() = default;
	//当线性表为空时返回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(std::ostream& out)const = 0;
};
template<typename T>
class stack
{
public:
	virtual ~stack() = default;
	virtual bool empty()const = 0; //当且仅当栈为空返回true
	virtual int size()const = 0; //返回栈中元素个数
	virtual T& top() = 0; //返回栈顶元素
	virtual void pop() = 0; //删除栈顶元素
	virtual void push(const T& theElement) = 0; //将元素theElement压入栈顶
};

chain类的定义

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;
	}
};

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(std::ostream& out)const override;

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

template<typename T>
chain<T>::chain(int initialCapacity = 10)
{
	if (initialCapacity <= 0) {
		std::ostringstream s;
		s << "Initial Capacity is " << initialCapacity << ",Must >=1";
		throw illegalParameterValue(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;
	}
	*/
}

template<typename T>
void chain<T>::checkIndex(int theIndex)const
{
	if ((theIndex<0) || (theIndex >= listSize)) {
		std::ostringstream s;
		s << "List size is " << listSize << ",theIndex is " << theIndex;
		throw illegalParameterValue(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;
}

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;
}

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;
	*/
}

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--;
}

template<typename T>
void chain<T>::insert(int theIndex, const T& theElement)
{
	if ((theIndex<0) || (theIndex>listSize)) {
		std::ostringstream s;
		s << "List size is " << listSize << ",theIndex is " << theIndex;
		throw illegalParameterValue(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++;
}

template<typename T>
void chain<T>::output(std::ostream& out)const
{
	for (chainNode<T>* tempNode = firstNode; tempNode != nullptr; tempNode = tempNode->next) {
		out << tempNode->element << "  ";
	}
}

derivedLinkedStack类的实现

template<class T>
class derivedLinkedStack :private chain<T>, public stack<T>
{
public:
	derivedLinkedStack(int initialCapacity = 10) :chain<T>(initialCapacity) {}
	bool empty()const override {
		return chain<T>::empty();
	}
	int size()const override {
		return chain<T>::size();
	}
	T& top() override{
		return chain<T>::get(0);
	}
	void pop() override {
		try { 
			earse(0); 
		}
		catch (illegalParameterValue) {
			throw stackEmpty();
		}
	}
	void push(const T& theElement) override{
		try {
			insert(0, theElement);
		}
		catch (illegalParameterValue) {
			throw stackEmpty();
		}
	}
};

主函数

int main()
{
	derivedLinkedStack<int> *myStack = new derivedLinkedStack<int>(5);

	myStack->push(1);
	myStack->push(2);
	myStack->push(3);

	std::cout << "Current size:" << myStack->size() << std::endl;
	std::cout << "Top:" << myStack->top() << std::endl;

	myStack->pop();

	std::cout << "Current size:" << myStack->size() << std::endl;
	std::cout << "Top:" << myStack->top() << std::endl;

	return 0;
}

C++(数据结构与算法):20---栈的实现(链表形式)_栈的实现

三、只继承于stack类实现
  • 我们也可以不继承于chain,自定定义arrayStack,然后只继承于抽象类stack,由此改进代码的时间性能

代码设计

头文件定义

#include <stdio.h>
#include <stdlib.h>
#include <sstream>
#include <iostream>
#include <string>
#include <algorithm>
#include <numeric>
#include <iterator>

using std::cout;
using std::endl;
using std::string;

异常类定义

class illegalParameterValue
{
	string message;
public:
	illegalParameterValue(const char *theMessage = "Illegal Parameter Value") :message(theMessage) {}
	const char *what() {
		return message.c_str();
	}
};

class stackEmpty
{
public:
	stackEmpty(string theMessage ="Invalid operation on empty stack")
	{
		message = theMessage;
	}
	const char *what() {
		return message.c_str();
	}
private:
	string message;
};

chainNode链表节点结构定义

template<class T>
struct chainNode
{
	chainNode() = default;
	chainNode(const T& theElement) {
		element = theElement;
	}
	chainNode(const T& theElement, chainNode<T> *theNext) {
		element = theElement;
		next = theNext;
	}
	T element;
	chainNode<T> *next;
};

stack抽象类定义

template<typename T>
class stack
{
public:
	virtual ~stack() = default;
	virtual bool empty()const = 0; //当且仅当栈为空返回true
	virtual int size()const = 0; //返回栈中元素个数
	virtual T& top() = 0; //返回栈顶元素
	virtual void pop() = 0; //删除栈顶元素
	virtual void push(const T& theElement) = 0; //将元素theElement压入栈顶
};

linkedStack类的定义

template<class T>
class linkedStack :public stack<T>
{
public:
	linkedStack(int initialCapacity = 10);
	~linkedStack();

	bool empty()const override;
	int size()const override;
	T& top()override;
	void pop()override;
	void push(const T& theElement)override;
private:
	chainNode<T> *stackTop;
	int stackSize;
};

template<class T>
linkedStack<T>::linkedStack(int initialCapacity = 10)
{
	stackTop = nullptr;
	stackSize = 0;
}

template<class T>
linkedStack<T>::~linkedStack()
{
	while (stackTop!=nullptr) {
		chainNode<T> *tempNode = stackTop->next;
		delete stackTop;
		stackTop = tempNode;
	}
}

template<class T>
bool linkedStack<T>::empty()const
{
	return stackSize == 0;
}

template<class T>
int linkedStack<T>::size()const
{
	return stackSize;
}

template<class T>
T& linkedStack<T>::top()
{
	if (stackSize <= 0) {
		throw stackEmpty();
	}

	return stackTop->element;
}

template<class T>
void linkedStack<T>::pop()
{
	if (stackSize <= 0) {
		throw stackEmpty();
	}

	chainNode<T>* tempNode = stackTop->next;
	delete stackTop;
	stackTop = tempNode;
	stackSize--;
}

template<class T>
void linkedStack<T>::push(const T& theElement)
{
	stackTop = new chainNode<T>(theElement, stackTop);
	stackSize++;
}

主函数

int main()
{
	linkedStack<int> *myStack = new linkedStack<int>;

	myStack->push(1);
	myStack->push(2);
	myStack->push(3);

	std::cout << "Current size:" << myStack->size() << std::endl;
	std::cout << "Top:" << myStack->top() << std::endl;

	myStack->pop();

	std::cout << "Current size:" << myStack->size() << std::endl;
	std::cout << "Top:" << myStack->top() << std::endl;

	return 0;
}

C++(数据结构与算法):20---栈的实现(链表形式)_#include_02