/* * 測試例,主函數位於這個文件中 * extendedChain.cpp */ #include<iostream> #include<numeric> #include"extendedchain.h" using namespace std; int main(void) { extendedChain<int> y; y.insert(0,2); y.insert(1,6); y.insert(0,1); y.insert(2,4); y.insert(3,5); y.insert(2,3); cout<<"after insert some elements:"<<endl; cout<<"size of y = "<<y.size()<<endl; y.erase(4); y.erase(0); y.push_back(6); cout << "List y should be 1 2 3 6" << endl; cout << "Size of y = " << y.size() << endl; cout << y << endl; y.insert(3,4); y.insert(0,0); cout << "List y should be 0 1 2 3 4" << endl; cout << "Size of y = " << y.size() << endl; cout << y << endl; y.clear(); y.push_back(1); y.push_back(2); y.push_back(3); cout << "Appended 3 integers, list y should be 1 2 3" << endl; cout << "Size of y = " << y.size() << endl; cout << y << endl; //迭代器這部分的測試是有問題的,代碼老是提示未定義的錯誤,還未找到問題點。之後再找。 /******************************************************************/ // 測試 iterator /* cout << "Ouput using forward iterators pre and post ++" << endl; for (extendedChain<int>::iterator i = y.begin(); i != y.end(); i++) cout << *i << " "; cout << endl; for (extendedChain<int>::iterator i = y.begin(); i != y.end(); ++i) { cout << *i << " "; *i += 1; } cout << endl; cout << "Incremented by 1 list is " << y << endl; // try out an STL algorithm int sum = accumulate(y.begin(), y.end(), 0); cout << "The sum of the elements is " << sum << endl; */ /*******************************************************************************/ return 0; }
/* * 擴展的抽象線性表的類,其中只是在原有線性表抽象類的基礎上,添加了幾個抽象函數 * extendedLinearList.h */ #ifndef EXTENDEDLINEARLIST_H #define EXTENDEDLINEARLIST_H #include<iostream> #include"linearlist.h" using namespace std; template<class T> class extendedLinearList : linearList<T> { public: virtual ~extendedLinearList(){} virtual void clear() = 0;//刪除鏈表 virtual void push_back(const T& theELement) = 0;//在鏈表尾部插入新元素 }; #endif // EXTENDEDLINEARLIST_H
擴展後的鏈表添加了lastNode指針,是一個指向鏈表的尾節點的指針。
利用lastNode指針,能夠在時間複雜度爲O(1)的狀況下在鏈表尾部插入新元素。
數據成員lastNode有時須要更改,由於在刪除和插入元素的時候會改變尾節點,這時就要更新指向尾節點的指針lastNode。
如下的extendedChain要完成的工做有:node
/* * 擴展後的鏈表的具體類實現 * extendedChain.h */ #ifndef EXTENDEDCHAIN_H #define EXTENDEDCHAIN_H #include<iostream> #include<sstream> #include<string> #include"extendedlinearlist.h" #include"chainwithiterator.h" #include"myexceptions.h" using namespace std; template<class T> class extendedChain : public extendedLinearList<T>,public chain<T> { public: extendedChain(int initialCapacity = 10): chain<T>(initialCapacity){} extendedChain(const extendedChain<T>& c): chain<T>(c){} /* * 各個函數的實現和聲明 */ bool empty()const{return listSize == 0;} int size() const{return listSize;} T& get(int theIndex) const { return chain<T>::get(theIndex); } int indexOf(const T &theELement) const { return chain<T>::indexOf(theELement); } void erase(int theIndex); void insert(int theIndex,const T& theElement); //子類中新添加的函數,功能是刪除鏈表 void clear() { while(firstNode != NULL) { chainNode<T>* nextNode = firstNode->next; delete firstNode; firstNode = nextNode; } listSize = 0; } //子類中新添加的元素,功能爲在鏈表尾部插入新元素 void push_back(const T& theElement); void output(ostream& out) const { chain<T>::output(out); } //清空鏈表 void zero() { firstNode = NULL; listSize = 0; } //迭代器類的定義 class iterator { public: typedef forward_iterator_tag iterator_category; typedef T value_type; typedef ptrdiff_t difference_type; typedef T* pointer; typedef T& reference; //構造函數 iterator(chainNode<T>* theNode = NULL) { node = theNode; } T& operator*() const{return node->element;} T* operator->() const{return &node->element;} //前加 iterator& operator++() { node = node->next; return *this; } //後加 iterator operator++(int) { iterator old = *this; node = node->next; return old; } //不等於 bool operator!=(const iterator right) const { return node != right.node; } //等於 bool operator == (const iterator right) const { return node = right.node; } protected: chainNode<T>* node; }; //迭代器 iterator bebin(){return iterator(firstNode);} iterator end(){return iterator(NULL);} protected: chainNode<T>* lastNode = NULL; chainNode<T>* firstNode = NULL; void checkIndex(int theIndex) const; int listSize = 0; }; template<class T> void extendedChain<T>::erase(int theIndex) { checkIndex(theIndex); chainNode<T>* deleteNode; if(theIndex == 0) { deleteNode = firstNode; firstNode = firstNode->next; } else { chainNode<T>* p = firstNode; for(int i = 0;i < theIndex-1;i++) { p = p->next; } deleteNode = p->next; p->next = p->next->next; if(deleteNode == lastNode) lastNode = p; } listSize--; delete deleteNode; } template<class T> void extendedChain<T>::insert(int theIndex, const T &theElement) { if(theIndex < 0 || theIndex > listSize) { ostringstream s; s <<"index = "<<theIndex << " size = "<<listSize; throw illegalIndex(s.str()); } if(theIndex == 0) { firstNode = new chainNode<T>(theElement,firstNode); if(listSize == 0) lastNode = firstNode; } else { chainNode<T>* p = firstNode; for(int i = 0;i < theIndex-1;i++) { p = p->next; } p->next = new chainNode<T>(theElement,p->next); if(listSize == theIndex) lastNode = p->next; } listSize++; } template<class T> void extendedChain<T>::push_back(const T& theElement) { chainNode<T>* newNode = new chainNode<T>(theElement,NULL); if(firstNode == NULL) firstNode = lastNode = newNode; else { lastNode->next = newNode; lastNode = newNode; } listSize++; } template<class T> void extendedChain<T>::checkIndex(int theIndex) const { if(theIndex < 0 || theIndex >= listSize) { ostringstream s; s <<"index = "<<theIndex<<" size = "<<listSize; throw illegalIndex(s.str()); } } #endif // EXTENDEDCHAIN_H
chainNode.hios
/* * 鏈表節點定義 * chainNode.h */ #ifndef CHAINNODE_H #define CHAINNODE_H template<class 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; } }; #endif // CHAINNODE_H
chainWithIterator.h函數
/* * 加入了迭代器的鏈表 * chainWithIterator.h */ #ifndef CHAINWITHITERATOR_H #define CHAINWITHITERATOR_H #include<iostream> #include<sstream> #include<string> #include"linearlist.h" #include"chainnode.h" #include"myexceptions.h" using namespace std; class linkedDigraph; template <class T> class linkedWDigraph; template<class T> class chain : public linearList<T> { friend linkedDigraph; friend linkedWDigraph<int>; friend linkedWDigraph<float>; friend linkedWDigraph<double>; public: //構造函數 chain(int initialCapacity = 10); //複製構造函數 chain(const chain<T>&); //析構函數 ~chain(); //判斷鏈表是否空 bool empty() const{return listSize == 0;} //鏈表元素個數 int size() const{return listSize;} //獲取索引指向的元素 T& get(int theIndex) const; //獲取元素指向的索引 int indexOf(const T& theElement) const; //刪除索引指向的元素 void erase(int theIndex); //在索引位置插入元素 void insert(int theIndex,const T& theElement); //將鏈表元素插入輸出流 void output(ostream &out) const; //迭代器 class iterator; iterator bebin(){return iterator(firstNode);} iterator end(){return iterator(NULL);} //迭代器類的定義 class iterator { public: typedef forward_iterator_tag iterator_category; typedef T value_type; typedef ptrdiff_t difference_type; typedef T* pointer; typedef T& reference; //構造函數 iterator(chainNode<T>* theNode = NULL) { node = theNode; } T& operator*() const{return node->element;} T* operator->() const{return &node->element;} //前加 iterator& operator++() { node = node->next; return *this; } //後加 iterator operator++(int) { iterator old = *this; node = node->next; return old; } //不等於 bool operator!=(const iterator right) const { return node != right.node; } //等於 bool operator == (const iterator right) const { return node = right.node; } protected: chainNode<T>* node; }; protected: void checkIndex(int theIndex) const;//檢查索引是否合法 chainNode<T>* firstNode;//指向鏈表第一個元素 int listSize;//鏈表元素個數 }; /* * 類中某些函數的具體實現 */ template<class T> chain<T>::chain(int initialCapacity) { if(initialCapacity < 1) { ostringstream s; s <<"Initial capacity = "<<initialCapacity<<"Must be > 0"; throw illegalParameterValue(s.str()); } firstNode = NULL; listSize = 0; } template<class T> chain<T>::chain(const chain<T> &theList) { listSize = theList.listSize; if(listSize == 0) { firstNode = NULL; return; } //鏈表非空 chainNode<T>* sourceNode = theList.firstNode; firstNode = new chainNode<T>(sourceNode->element); sourceNode = sourceNode->next; chainNode<T>* targetNode = firstNode; while(sourceNode != NULL) { targetNode->next = new chainNode<T>(sourceNode->element); targetNode = targetNode->next; sourceNode = sourceNode->next; } targetNode->next = NULL; } template<class T> chain<T>::~chain() { chainNode<T> *nextNode; while(firstNode != NULL) { nextNode = firstNode->next; delete firstNode; firstNode = nextNode; } } template<class T> void chain<T>::checkIndex(int theIndex) const { if(theIndex < 0 || theIndex >= listSize) { ostringstream s; s <<"index = " <<theIndex <<" size = "<<listSize; throw illegalIndex(s.str()); } } template<class T> T& chain<T>::get(int theIndex) const { checkIndex(theIndex); chainNode<T>* currentNode = firstNode; for(int i = 0;i<theIndex;i++) { currentNode = currentNode->next; } return currentNode->element; } template<class T> int chain<T>::indexOf(const T &theElement) const { chainNode<T>* currentNode = firstNode; int index = 0; while(currentNode != NULL && currentNode->element != theElement) { currentNode = currentNode->next; index++; } if(currentNode == NULL) return -1; else return index; } template<class T> void chain<T>::erase(int theIndex) { checkIndex(theIndex); chainNode<T>* deleteNode; if(theIndex == 0) { deleteNode = firstNode; firstNode = firstNode->next; } else { chainNode<T>* p = firstNode; for(int i = 0;i < theIndex -1;i++) { p = p->next; } deleteNode = p->next; p->next = p->next->next; } listSize--; delete deleteNode; } template<class T> void chain<T>::insert(int theIndex, const T &theElement) { if(theIndex < 0 || theIndex > listSize) { ostringstream s; s <<"index = "<<theIndex <<" size = "<<listSize; throw illegalIndex(s.str()); } if(theIndex == 0) { firstNode = new chainNode<T>(theElement,firstNode); } else { chainNode<T>* p = firstNode; for(int i = 0;i < theIndex;i++) p = p->next; p->next = new chainNode<T>(theElement,p->next); } listSize++; } template<class T> void chain<T>::output(ostream &out) const { for(chainNode<T>* currentNode = firstNode; currentNode != NULL; currentNode = currentNode->next) { out<<currentNode->element<< " "; } } template<class T> ostream& operator<<(ostream& out,const chain<T>& x) { x.output(out); return out; } #endif // CHAINWITHITERATOR_H
linearList.hpost
/* * 舊的線性表的抽象類 * linearList.h */ #ifndef LINEARLIST_H #define LINEARLIST_H #include<iostream> using namespace std; template<class T> class linearList { public: virtual ~linearList(){} virtual bool empty() const = 0; virtual int size() const = 0; virtual T& get(int theIndex) const = 0; virtual int indexOf(const T& theELement) const = 0; virtual void erase(int theIndex) = 0; virtual void insert(int theIndex,const T& theElement)=0; virtual void output(ostream& out) const = 0; }; #endif // LINEARLIST_H
myExceptions.h測試
/* * 異常類的定義和實現 * myException.h */ #ifndef MYEXCEPTIONS_H #define MYEXCEPTIONS_H #include<string> using namespace std; //非法參數 class illegalParameterValue { public: illegalParameterValue(string theMessage = "Illegal parameter value") { message = theMessage; } void outputMessage() { cout <<message <<endl; } private: string message; }; //非法輸入的數據 class illegalInputData { public: illegalInputData(string theMessage = "Illegal data input") { message = theMessage; } void outputMessage() { cout<<message<<endl; } private: string message; }; //非法索引 class illegalIndex { public: illegalIndex(string theMessage = "Illegal Index") { message = theMessage; } void outputMessage() { cout<<message<<endl; } private: string message; }; #endif // MYEXCEPTIONS_H