-
本文代码下载链接:
- 方式1:公众号【多栖技术控小董】回复【3576】免费获取下载链接。
- 方式2:CSDN下载链接:
- derivedLinkedStack类代码的下载javascript:void(0)
- linkedStack代码的下载javascript:void(0)
- 方式3:Github下载链接https://github.com/dongyusheng/Interview-algorithm/tree/master/c%2B%2BAlgorithms(进入之后下载里面的derivedArrayStack.zip、arrayStack.zip文件)
- 若用链表实现,我们将考虑使用链表的左端还是右端来作为栈顶
- 如果使用链表右端作为栈顶,那么栈操作top、push、pop的实现需要调用链表方法get(size()-1)、insert(size(),theElement)和rease(size()-1)。每一个链表方法需要用时O(size())
- 如果使用链表左端作为栈顶,那么栈操作调用链表方法get(0)、insert(0,theElement)和rease(0),其中每一个链表方法需要用时Θ(1)
- 因此我们选择链表的左端作为栈顶
- 前面用链表使用线性表的时候,我们使用到chain类,此处我们将定义一个类derivedLinkedStack继承于chain与stack来实现栈的链表形式
三、只继承于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; }
- 我们也可以不继承于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; }