C++ examples for Data Structure:Stack
Infix-to-Postfix Conversion
#include <iostream> #include <string> template <typename NODETYPE> class List;/*from w w w. j a va 2 s . com*/ template <typename NODETYPE> class ListNode { friend class List<NODETYPE>; // make List a friend public: explicit ListNode(const NODETYPE& info) : data(info), nextPtr(0) {} // return copy of data in node NODETYPE getData() const { return data; } // return pointer to next node ListNode<NODETYPE>* next() const { return nextPtr; } private: NODETYPE data; ListNode<NODETYPE> *nextPtr; }; template <typename NODETYPE> class List { public: List(); ~List(); void insertAtFront(const NODETYPE &); void insertAtBack(const NODETYPE &); bool removeFromFront(NODETYPE &); bool removeFromBack(NODETYPE &); void concatenate(List<NODETYPE> &); // is List empty bool isEmpty() const { return firstPtr == 0; } void print() const; // print sz of list int size() const { return sz; } // return pointer to first node ListNode<NODETYPE>* begin() const { return firstPtr; } // return pointer to last node ListNode<NODETYPE>* end() const { return lastPtr; } private: ListNode<NODETYPE> *firstPtr; // pointer to first node ListNode<NODETYPE> *lastPtr; // pointer to last node int sz; // utility function to allocate new node ListNode<NODETYPE> *getNewNode(const NODETYPE &); }; template <typename NODETYPE> List<NODETYPE>::List() : firstPtr(0), lastPtr(0), sz(0) {} template <typename NODETYPE> List<NODETYPE>::~List() { if (!isEmpty()) { ListNode<NODETYPE> *currentPtr = firstPtr; // delete remaining nodes while (currentPtr != 0) { ListNode<NODETYPE> *tempPtr = currentPtr; currentPtr = currentPtr->nextPtr; delete tempPtr; } } } template <typename NODETYPE> void List<NODETYPE>::insertAtFront(const NODETYPE &value) { ListNode<NODETYPE> *newPtr = getNewNode(value); if (isEmpty()) { firstPtr = lastPtr = newPtr; // new list only has one node } else { newPtr->nextPtr = firstPtr; // point new node to previous list node firstPtr = newPtr; } ++sz; } template <typename NODETYPE> void List<NODETYPE>::insertAtBack(const NODETYPE &value) { ListNode<NODETYPE> *newPtr = getNewNode(value); if (isEmpty()) { firstPtr = lastPtr = newPtr; // new list has only one node } else { lastPtr->nextPtr = newPtr; lastPtr = newPtr; } ++sz; } template <typename NODETYPE> bool List<NODETYPE>::removeFromFront(NODETYPE &value) { if (isEmpty()) { // list is empty return false; } else { ListNode<NODETYPE> *tempPtr = firstPtr; if (firstPtr == lastPtr) firstPtr = lastPtr = 0; // no nodes remain after removal else firstPtr = firstPtr->nextPtr; // point to previous 2nd node value = tempPtr->data; delete tempPtr; --sz; return true; } } template <typename NODETYPE> bool List<NODETYPE>::removeFromBack(NODETYPE &value) { if (isEmpty()) { // list is empty return false; } else { ListNode<NODETYPE> *tempPtr = lastPtr; if (firstPtr == lastPtr) { // list has one element firstPtr = lastPtr = 0; // no nodes remain after removal } else { ListNode<NODETYPE> *currentPtr = firstPtr; // locate second to last element while (currentPtr->nextPtr != lastPtr) currentPtr = currentPtr->nextPtr; // move to next node lastPtr = currentPtr; // remove last node currentPtr->nextPtr = 0; // this is now the last node } value = tempPtr->data; delete tempPtr; --sz; return true; } } template <typename NODETYPE> void List<NODETYPE>::concatenate(List<NODETYPE> &listSecond) { ListNode<NODETYPE> *currentPtr = listSecond.firstPtr; while (currentPtr != 0) { insertAtBack(currentPtr->getData()); currentPtr = currentPtr->nextPtr; } } template <typename NODETYPE> ListNode<NODETYPE> *List<NODETYPE>::getNewNode(const NODETYPE &value) { return new ListNode<NODETYPE>(value); } template <typename NODETYPE> void List<NODETYPE>::print() const { if (isEmpty()) { std::cout << "The list is empty\n\n"; return; } ListNode<NODETYPE> *currentPtr = firstPtr; while (currentPtr != 0) { std::cout << currentPtr->getData() << ' '; currentPtr = currentPtr->nextPtr; } } template <typename STACKTYPE> class Stack : private List<STACKTYPE> { public: void push(const STACKTYPE &data) { this->insertAtBack(data); } bool pop(STACKTYPE data) { return this->removeFromBack(data); } bool isStackEmpty() const { return this->isEmpty(); } void printStack() const { this->print(); } STACKTYPE stackTop() const { return this->end()->getData(); } }; bool isOperator(const char& c) { switch (c) { case '+': case '-': case '*': case '/': case '^': case '%': return true; break; default: return false; break; } } bool precedence(const char& operator1, const char& operator2) { switch (operator1) { case '+': case '-': return ((operator2 == '-') || (operator2 == '+')); case '*': case '/': case '%': return ((operator2 == '*') || (operator2 == '/') || (operator2 == '%') || (operator2 == '+') || (operator2 == '-')); case '^': return true; default: return false; } } std::string convertToPostfix(std::string& infix) { std::string postfix; // final expression Stack<char> postfixStack; postfixStack.push('('); infix += ')'; for (char& c : infix) { if (isdigit(c)) postfix += c; if (c == '(') postfixStack.push(c); if (isOperator(c)) { while (isOperator(postfixStack.stackTop()) && precedence(postfixStack.stackTop(), c)) { postfix += postfixStack.stackTop(); postfixStack.pop(postfixStack.stackTop()); } postfixStack.push(c); } if (c == ')') { while (postfixStack.stackTop() != '(') { postfix += postfixStack.stackTop(); postfixStack.pop(postfixStack.stackTop()); } postfixStack.pop(')'); } } return postfix; } int main(int argc, const char* argv[]) { std::string infix; // original expression std::cout << "Enter infix expression: "; std::getline(std::cin, infix); std::cout << convertToPostfix(infix) << std::endl; return 0; }