Advertisement
Vermiculus

LinkedList<T>

Feb 11th, 2012
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.38 KB | None | 0 0
  1. /*
  2.  *  LinkedList.h
  3.  *  Project 1
  4.  *
  5.  *  Created by Sean Allred on 2/1/12.
  6.  *  Copyright 2012 St. Mary's College of Maryland. All rights reserved.
  7.  *
  8.  */
  9.  
  10. #include <cstdlib>
  11. #include <iostream>
  12.  
  13. using namespace std;
  14.  
  15. const bool VERBOSE = true;
  16. const bool SUPERVERBOSE = VERBOSE && false;
  17.  
  18. template <typename T> class LinkedList;
  19. template <typename T> ostream& operator << (ostream&, LinkedList<T>&);
  20. template <typename T> istream& operator >> (istream&, LinkedList<T>&);
  21.  
  22. template <typename T>
  23. struct Node {
  24.     Node<T>(T v) : value(v), used(true) {}
  25.     Node<T>(T v, bool u) : value(v), used(u) {}
  26.     Node<T> *prev;
  27.     Node<T> *next;
  28.     T value;
  29.    
  30.     bool used;
  31. };
  32.  
  33. template <typename T>
  34. class LinkedList {
  35.    
  36.     friend ostream& operator << <T>(ostream&, LinkedList<T>&);
  37.     friend istream& operator >> <T>(istream&, LinkedList<T>&);
  38.    
  39. public:
  40.     /* (CON)(DE)STRUCTORS */
  41.     /* LinkedList()
  42.       Creates an empty LinkedList and
  43.       initializes 'head' and 'tail'.
  44.      */
  45.     LinkedList();
  46.    
  47.     /* LinkedList(int)
  48.       Creates an 'empty' LinkedList with
  49.       however many nodes are specified.
  50.      
  51.       Note that each node is *supposed* to be
  52.       rubbish, but Xcode seems to automagically
  53.       initialize primitives for you.
  54.      */
  55.     LinkedList(int);
  56.    
  57.     /*
  58.       Copy constructor
  59.      */
  60.     LinkedList(const LinkedList&);
  61.    
  62.     /* ~LinkedList()
  63.       Frees all memory used by the object
  64.       by removing literally every last node.
  65.      
  66.       The method trim() is called until the
  67.       size is zero, then 'head' and 'tail'
  68.       are deleted.
  69.      */
  70.     ~LinkedList();
  71.     /* END (CON)(DE)STRUCTORS */
  72.    
  73.     /*
  74.       public interface to 's', which denotes
  75.       how many nodes are in the LinkedList
  76.      */
  77.     int size();
  78.    
  79.     /*
  80.        Deletes the cell at the
  81.        ith index
  82.      */
  83.     T delCell(int);
  84.    
  85.     void trimEmpty();
  86.    
  87.     /*
  88.        Inserts a value (T) such that
  89.        its index is (int)
  90.      */
  91.     int insert(T, int);
  92.    
  93.     /*
  94.        Shorthand append
  95.      */
  96.     void operator += (T);
  97.    
  98.     /*
  99.      Successfully sets a value
  100.      from the list (shorthand set(int, T))
  101.      */
  102.     T& operator [](const int);
  103.    
  104.     /*
  105.      Successfully gets a value
  106.      from the list (shorthand get(int))
  107.      */
  108.     T operator [](const int) const;
  109.    
  110.     /*
  111.        Reference assignment
  112.      */
  113.     void operator =(LinkedList&);
  114.    
  115.     /*
  116.        Takes off the last element
  117.      */
  118.     T trim();
  119.    
  120. //protected:
  121.     Node<T> *head;
  122.     Node<T> *tail;
  123.    
  124. //private:
  125.     Node<T>* get(int);
  126.    
  127.     Node<T>* set(T, int);
  128.    
  129.     int append(T);
  130.    
  131.     int append(T, bool);
  132.      
  133.     void print();
  134.    
  135.     int insertAfter(T, Node<T>*);
  136.    
  137.     int insertBefore(T, Node<T>*);
  138.    
  139.     T destroy(Node<T>*);
  140.    
  141.     void expand(int);
  142.    
  143.     void prime();
  144.    
  145.     int s;
  146.    
  147.     int minsize;
  148. };
  149.  
  150. /*
  151.  *  LinkedList.cpp
  152.  *  Project 1
  153.  *
  154.  *  Created by Sean Allred on 2/8/12.
  155.  *  Copyright 2012 St. Mary's College of Maryland. All rights reserved.
  156.  *
  157.  */
  158.  
  159.  
  160.  
  161. /*******************************/
  162. /* Constructors and Destructor */
  163. /*******************************/
  164.  
  165. template <typename T>
  166. LinkedList<T>::LinkedList() {
  167.     this->prime();
  168. }
  169.  
  170. template <typename T>
  171. LinkedList<T>::LinkedList(int i) {
  172.     this->prime();
  173.    
  174.     this->minsize = i;
  175.    
  176.     this->expand(i);
  177. }
  178.  
  179. template <typename T>
  180. LinkedList<T>::LinkedList(const LinkedList<T>& l) {
  181.     this->prime();
  182.    
  183.     Node<T> *n = l.head;
  184.     while (n != NULL) {
  185.         this->append(n->value);
  186.         n = n->next;
  187.     }
  188. }
  189.  
  190. template <typename T>
  191. LinkedList<T>::~LinkedList<T>() {
  192.     if(VERBOSE) {
  193.         printf("Destroying List at %p\n", this);
  194.     }
  195.     while (s != 0) {
  196.         this->trim();
  197.     }
  198.     if (VERBOSE) {
  199.         printf("List at %p destroyed\n", this);
  200.     }
  201. }
  202.  
  203. /**********************/
  204. /* Operator Overloads */
  205. /**********************/
  206.  
  207. template <typename T> void
  208. LinkedList<T>::operator = (LinkedList<T>& l) {
  209.     this->head = l.head;
  210.     this->tail = l.tail;
  211. }
  212.  
  213. template <typename T> void
  214. LinkedList<T>::operator += (T val) {
  215.     this->append(val);
  216. }
  217.  
  218. template <typename T> T& // set
  219. LinkedList<T>::operator [] (const int i) {
  220.     return this->get(i)->value;
  221. }
  222.  
  223. template <typename T> T // get
  224. LinkedList<T>::operator [] (const int i) const {
  225.     return this->get(i)->value;
  226. }
  227.  
  228. /***** Insertion and Extraction *****/
  229.  
  230. template <typename T> ostream&
  231. operator << (ostream &os, LinkedList<T> &list) {
  232.     Node<T> *p = list.head;
  233.     os << "{";
  234.     while (p->next != NULL) {
  235.         os << p->value << ", ";
  236.         p = p->next;
  237.     }
  238.     os << p->value << "}";
  239.     return os;
  240. }
  241.  
  242. template <typename T> istream&
  243. operator >> (istream &is, LinkedList<T> &list) {
  244.     T val;
  245.    
  246.     is >> val;
  247.    
  248.     list.append(val);
  249.    
  250.     return is;
  251. }
  252.  
  253. /********************/
  254. /* Member Functions */
  255. /********************/
  256.  
  257. template <typename T>
  258. void    LinkedList<T>::prime() {
  259.     if(VERBOSE) {
  260.         printf("Created LinkedList at %p.\n", this);
  261.     }
  262.     this->s = 0;
  263.     this->minsize = 0;
  264.    
  265.     this->head = NULL;
  266.     this->tail = NULL;
  267. }
  268.  
  269. /***** Accessors *****/
  270.  
  271. template <typename T>
  272. int     LinkedList<T>::size() {
  273.     return this->s;
  274. }
  275.  
  276. template <typename T>
  277. Node<T>* LinkedList<T>::get(int i) {
  278.     if (i >= this->size()) {
  279.         this->expand(i - this->size() + 1);
  280.         ///
  281.         this->tail->used = true;
  282.     }
  283.    
  284.     Node<T> *r = this->head;
  285.     while (i > 0 && r != this->tail) {
  286.         r = r->next;
  287.         i--;
  288.     }
  289.    
  290.     return r;
  291. }
  292.  
  293. /***** Mutators *****/
  294.  
  295. /* Neutral */
  296.  
  297. template <typename T>
  298. Node<T>*    LinkedList<T>::set(T val, int i) {
  299.     Node<T> *n = this->get(i);
  300.    
  301.     n->value = val;
  302.     n->used = true;
  303.    
  304.     return n;
  305. }
  306.  
  307. /* Constructive */
  308.  
  309. template <typename T>
  310. int     LinkedList<T>::append(T val) {
  311.     return this->append(val, true);
  312. }
  313.  
  314. template <typename T>
  315. int     LinkedList<T>::append(T val, bool used) {
  316.    
  317.     Node<T> *newnode = new Node<T>(val, used);
  318.    
  319.     if(SUPERVERBOSE) {
  320.         printf("Appending value '%d' at %p\n", val, newnode);
  321.     }
  322.    
  323.     switch (s) {
  324.         case 0:
  325.             this->head = newnode;
  326.             newnode->prev = NULL;
  327.             break;
  328.            
  329.         case 1:
  330.             this->head->next = newnode;
  331.             newnode->prev = this->head;
  332.             break;
  333.            
  334.         default:
  335.             this->tail->next = newnode;
  336.             //newnode->prev = this->tail->prev;
  337.             newnode->prev = this->get(s - 1);
  338.     }
  339.    
  340.     newnode->next = NULL;
  341.     this->tail = newnode;
  342.    
  343.     s++;
  344.     return 0;
  345. }
  346.  
  347. template <typename T>
  348. int     LinkedList<T>::insert(T val, int i) {
  349.     if (s == 0 || s == 1) {
  350.         s++;
  351.         return this->append(val);
  352.     }
  353.     return this->insertAfter(val, this->get(i));
  354. }
  355.  
  356. template <typename T>
  357. int     LinkedList<T>::insertAfter(T val, Node<T> *oldnode) {
  358.     if (oldnode == this->tail) {
  359.         return this->append(val);
  360.     }
  361.     Node<T> *newnode = new Node<T>(val);
  362.    
  363.     newnode->prev = oldnode;
  364.     newnode->next = oldnode->next;
  365.    
  366.     newnode->next->prev = newnode;
  367.     oldnode->next = newnode;
  368.    
  369.     s++;
  370.    
  371.     return 0;
  372. }
  373.  
  374. template <typename T>
  375. void    LinkedList<T>::expand(int i) {
  376.     while (i > 0) {
  377.         T *n = new T;
  378.         this->append(*n, false);
  379.         i--;
  380.     }
  381. }
  382.  
  383. /* Destructive */
  384.  
  385. template <typename T>
  386. T       LinkedList<T>::trim() {
  387.     return this->delCell(this->size()-1);
  388. }
  389.  
  390. template <typename T>
  391. T       LinkedList<T>::delCell(int i) {
  392.     Node<T> *del = this->get(i);
  393.    
  394.     if (del == this->head) {
  395.         this->head = del->next;
  396.     } else {
  397.         del->prev->next = del->next;
  398.     }
  399.    
  400.     if (del == this->tail) {
  401.         this->tail = del->prev;
  402.     } else {
  403.         del->next->prev = del->prev;
  404.     }  
  405.    
  406.     int r = this->destroy(del);
  407.    
  408.     if (s == 1) {
  409.         this->tail = this->head;
  410.     }
  411.    
  412.     if(this->s != 0 && !this->tail->used) {
  413.         this->trimEmpty();
  414.     }
  415.    
  416.     return r;
  417. }
  418.  
  419. template <typename T>
  420. T       LinkedList<T>::destroy(Node<T> *n) {
  421.     T r = n->value;
  422.     delete n;
  423.     s--;
  424.    
  425.     if(SUPERVERBOSE) {
  426.         printf("Value '%d' at %p destroyed\n", r, n);
  427.     }
  428.    
  429.     return r;
  430. }
  431.  
  432. template <typename T>
  433. void    LinkedList<T>::trimEmpty() {
  434.     Node<T> *n = this->tail;
  435.    
  436.     while (this->s > this->minsize && this->s > 1 && !n->used ) {      
  437.        
  438.         n->prev->next = n->next;
  439.         this->tail = n->prev;  
  440.        
  441.         this->destroy(n);
  442.        
  443.         n = this->tail;
  444.     }
  445.    
  446.     if (this->s == 1 && !n->used) {
  447.         this->head = NULL;
  448.         this->tail = NULL;
  449.         destroy(n);
  450.     }
  451. }
  452.  
  453. template <typename T>
  454. void    LinkedList<T>::print() {
  455.     cout << *this;
  456. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement