Template Stack class definition derived from class List - C++ Data Structure

C++ examples for Data Structure:Stack

Description

Template Stack class definition derived from class List

Demo Code

#include <iostream>
template <typename NODETYPE>
class List;/*from w  w  w .  j  a  v a  2s  .  c  o m*/


template <typename STACKTYPE>
class Stack : private List<STACKTYPE> {
public:
  void push(const STACKTYPE &data) { this->insertAtFront(data); }
  bool pop(STACKTYPE &data) { return this->removeFromFront(data); }
  bool isStackEmpty() const { return this->isEmpty(); }
  void printStack() const { this->print(); }

private:
};


template <typename NODETYPE>
class ListNode {
  friend class List<NODETYPE>;  // make List a friend

public:
  explicit ListNode(const NODETYPE &);

  NODETYPE getData() const;

private:
  NODETYPE data;
  ListNode<NODETYPE> *nextPtr;
};

template <typename NODETYPE>
ListNode<NODETYPE>::ListNode(const NODETYPE &info) : data(info), nextPtr(0) {}

template <typename NODETYPE>
NODETYPE ListNode<NODETYPE>::getData() const {
  return data;
}


template <typename NODETYPE>
class List {
public:
  List();
  ~List();

  void insertAtFront(const NODETYPE &);
  void insertAtBack(const NODETYPE &);
  bool removeFromFront(NODETYPE &);
  bool removeFromBack(NODETYPE &);
  bool isEmpty() const;
  void print() const;

private:
  ListNode<NODETYPE> *firstPtr;  // pointer to first node
  ListNode<NODETYPE> *lastPtr;   // pointer to last node

                   // utility function to allocate new node
  ListNode<NODETYPE> *getNewNode(const NODETYPE &);
};

template <typename NODETYPE>
List<NODETYPE>::List() : firstPtr(0), lastPtr(0) {}

template <typename NODETYPE>
List<NODETYPE>::~List() {
  if (!isEmpty()) {
    std::cout << "Destroying Nodes...\n";
    ListNode<NODETYPE> *currentPtr = firstPtr;

    while (currentPtr != 0) {
      ListNode<NODETYPE> *tempPtr = currentPtr;
      std::cout << tempPtr->data << '\n';
      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;
  }
}

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

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;

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

template <typename NODETYPE>
bool List<NODETYPE>::isEmpty() const {
  return firstPtr == 0;
}

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;

  std::cout << "The list is: ";

  while (currentPtr != 0) {
    std::cout << currentPtr->data << ' ';
    currentPtr = currentPtr->nextPtr;
  }

  std::cout << "\n\n";
}


#include <iostream>

int main(int argc, const char* argv[]) {
  Stack<int> intStack;

  std::cout << "Processing an integer stack" << std::endl;

  for (int i = 0; i < 3; ++i) {
    intStack.push(i);
    intStack.printStack();
  }

  int popInteger;  // store int popped from stack

  while (!intStack.isStackEmpty()) {
    intStack.pop(popInteger);
    std::cout << popInteger << " popped from stack" << std::endl;
    intStack.printStack();
  }

  Stack<double> doubleStack;
  double value = 1.1f;

  std::cout << "Processing a double stack" << std::endl;

  for (int i = 0; i < 3; ++i) {
    doubleStack.push(value);
    doubleStack.printStack();
    value += 1.1f;
  }

  double popDouble;  // store double popped from stack

             // pop floating-point values from doubleStack
  while (!doubleStack.isStackEmpty()) {
    doubleStack.pop(popDouble);
    std::cout << popDouble << " popped from stack." << std::endl;
    doubleStack.printStack();
  }

  return 0;
}

Result


Related Tutorials