#ifndef LIST_H #define LIST_H #include using namespace std; template class DoubleLinkedList { private: template class Entry { private: Entry(const Entry&); Entry& operator=(const Entry&); public: Entry* next; Entry* pre; T* data; Entry(const T& obj); virtual ~Entry(); }; Entry* head; Entry* tail; int size; DoubleLinkedList& operator=(const DoubleLinkedList&); Entry* getEntryAt(int n) const; public: DoubleLinkedList(); virtual ~DoubleLinkedList(); void addFirst(const T& obj); void addLast(const T& obj); void addAt(int n, const T& obj); bool removeFirst(); bool removeLast(); bool removeAt(int n); T getFirst() const; T getLast() const; T get(int n) const; int getSize() const; }; // ¸ðµç Æ÷ÀÎÅÍ´Â NULL·Î ÃʱâÈ­ÇÏ¸ç »èÁ¦ÇÒ ¶§µµ ´Ù½Ã NULLÀ» °¡¸®Å°°ÔÇÑ´Ù. //--------------------- Entry Ŭ·¡½º Á¤ÀÇ ------------------- template DoubleLinkedList::Entry::Entry() : next(NULL), pre(NULL), data(NULL) {} template DoubleLinkedList::Entry::Entry(const T& obj) : next(NULL), pre(NULL) { data = new T(obj); } template DoubleLinkedList::Entry::~Entry() { delete data; } //--------------------- DoubleLinkedList ÅÛÇø´Å¬·¡½º Á¤ÀÇ ------------- template DoubleLinkedList::DoubleLinkedList() : head(NULL), tail(NULL), size(0) {} template DoubleLinkedList::~DoubleLinkedList() { while (getSize() != 0) removeFirst(); } /* * obj¸¦ ¸®½ºÆ®ÀÇ ¸Ç ¾Õ¿¡ Ãß°¡ÇÑ´Ù. */ template void DoubleLinkedList::addFirst(const T& obj) { if (size == 0) { head = new Entry(obj); tail = head; } else { head->pre = new Entry(obj); head->pre->next = head; head = head->pre; } size++; } /* * obj¸¦ ¸®½ºÆ®ÀÇ ¸¶Áö¸·¿¡ Ãß°¡ÇÑ´Ù. */ template void DoubleLinkedList::addLast(const T& obj) { if (size == 0) { addFirst(obj); return; } else { Entry* e = new Entry(obj); e->pre = tail; tail->next = e; tail = e; } size++; } /* * n ¹øÂ° Ç׸ñ¿¡ obj¸¦ Ãß°¡ÇÑ´Ù. */ template void DoubleLinkedList::addAt(int n, const T& obj) { if (n != 0 && n >= size || n < 0) { ostringstream sout; sout << "¹üÀ§¸¦ ³Ñ¾î¼¹½À´Ï´Ù.\n°¡´É¹üÀ§: 0 ~ " << size - 1 << " ¿äû: " << n; throw sout.str(); } else if (size <= 2) { if (getEntryAt(n) == head) { addFirst(obj); return; } else { addLast(obj); return; } } else { Entry* next = getEntryAt(n); Entry* pre = next->pre; Entry* nowEntry = new Entry(obj); nowEntry->next = next; next->pre = nowEntry; pre->next = nowEntry; nowEntry->pre = pre; size++; } } /* * ¸®½ºÆ®ÀÇ Ã¹¹øÂ° Ç׸ñÀ» »èÁ¦ÇÑ´Ù. * ÀúÀåµÈ °´Ã¼°¡ ¾øÀ¸¸é false°¡ ¸®ÅϵȴÙ. */ template bool DoubleLinkedList::removeFirst() { if (size == 0) return false; else { if (--size == 0) { delete head; head = tail = NULL; } else { head = head->next; delete head->pre; head->pre = NULL; } } return true; } /* * ¸®½ºÆ®ÀÇ ¸¶Áö¸· Ç׸ñÀ» »èÁ¦ÇÑ´Ù. */ template bool DoubleLinkedList::removeLast() { if (size == 0) { return false; } else { if (size == 1) { delete tail; head = tail = NULL; } else { tail = tail->pre; delete tail->next; tail->next = NULL; } } size--; return true; } /* * n¹øÂ° Ç׸ñÀ» »èÁ¦ÇÑ´Ù. */ template bool DoubleLinkedList::removeAt(int n) { if (n >= size || n < 0) { ostringstream sout; sout << "List°¡ ºñ¾ú°Å³ª ¹üÀ§¸¦ ³Ñ¾î¼¹½À´Ï´Ù.\n°¡´É¹üÀ§: 0 ~ " << size - 1 << ", ¿äû: " << n; throw sout.str(); } else if (size <= 2) { if (getEntryAt(n) == head) return removeFirst(); else return removeLast(); } else { Entry* pre = getEntryAt(n); pre->next - pre->next->next; pre->next->next->pre = pre; size--; } return true; } /* * ¸®½ºÆ®ÀÇ Ã¹¹øÂ° Ç׸ñ¿¡ ÀúÀåµÈ °´Ã¼¸¦ ¸®ÅÏÇÑ´Ù. * getSize()°¡ 0À̸é NULLÀÌ ¹ÝȯµÈ´Ù. */ template T DoubleLinkedList::getFirst() const { if (size == 0) throw "ÀúÀåµÈ Ç׸ñÀÌ ¾ø½À´Ï´Ù."; return *head->data; } /* * ¸®½ºÆ®ÀÇ ¸¶Áö¸· Ç׸ñ¿¡ ÀúÀåµÈ °´Ã¼¸¦ ¸®ÅÏÇÑ´Ù. * getSize()°¡ 0À̸é NULLÀÌ ¹ÝȯµÈ´Ù. */ template T DoubleLinkedList::getLast() const { if (size == 0) throw "ÀúÀåµÈ Ç׸ñÀÌ ¾ø½À´Ï´Ù."; return *tail->data; } /* * n¹øÂ° Ç׸ñÀÇ °´Ã¼¸¦ ¸®ÅÏÇÑ´Ù. */ template T DoubleLinkedList::get(int n) const { return *getEntryAt(n)->data; } /* * n¹øÂ° Ç׸ñÀ» ¸®ÅÏÇÑ´Ù. * ¾øÀ¸¸é NULLÀÌ ¹ÝÇѵȴÙ. */ template DoubleLinkedList::Entry* DoubleLinkedList::getEntryAt(int n) const { if (n >= size || n < 0) { ostringstream sout; sout << "List°¡ ºñ¾ú°Å³ª ¹üÀ§¸¦ ³Ñ¾î¼¹½À´Ï´Ù.\n°¡´É¹üÀ§: 0 ~ " << size - 1 << ", ¿äû: " << n; throw sout.str(); } Entry* e = head; while (n != 0) { e = e->next; n--; } return e; } template int DoubleLinkedList::getSize() const { return size; } #endif