線性表的抽象類實現適用於線性表和鏈表:函數
/* * 線性表的抽象類 */ template<class T> class linearList { public: virtual ~linearList(){}; virtual bool empty() const = 0;//線性表爲空,返回ture virtual int size() const = 0;//返回線性表的元素個數 virtual T& get(int theIndex) const = 0;//返回索引爲theIndex的索引 virtual int indexOf(const T& theElement) const = 0;//返回元素theElement第一次出現時的索引 virtual void erase(int theIndex) const = 0;//刪除索引爲theIndex的元素 virtual void insert(int theIndex,const T& theElement) const= 0;//插入元素 virtual void output(ostream& out) const = 0;//把線性表插入輸出流out };
這是對鏈表節點結構的實現:this
//鏈表節點定義 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; } };
對線性表抽象類的實現:指針
//鏈表結構定義 template<class T> class chain:public linearList<T> { public: //構造函數,複製構造函數和析構函數 chain(int initialCapacity = 10); chain(const chain<T>&); ~chain(); //抽象類中的函數 bool empty()const; int size() const; T& get(int theIndex) const; int indexOf(const T &theElement) const; void erase(int theIndex) const; void insert(int theIndex, const T &theElement) const; void output(ostream &out) const; protected: void checkIndex(int theIndex) const;//檢查索引是否有效 chainNode<T>* firstNode;//指向鏈表第一個節點的指針 int listSize;//線性表元素個數 };
鏈表具體類中全部函數的具體實現:code
/* * 鏈表結構中各類函數的具體實現 */ //構造函數 template<class T> chain<T>::chain(int initialCapacity) { if(initialCapacity > 0) { firstNode = NULL; listSize = 0; }else { cout<<"初始化的數據量必須大於0"<<endl; } } //複製構造函數 template<class T> chain<T>::chain(const chain<T>& theList) { listSize = theList.listSize; if(listSize == 0) { firstNode = NULL; return; } //鏈表theList爲非空 chainNode<T>* sourceNode = theList.firstNode; firstNode = new chainNode<T>(sourceNode->element);//複製線性表theList的首元素 sourceNode = sourceNode->next; chainNode<T>* targetNode = firstNode;//當前鏈表*this的最後一個節點 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() { //刪除鏈表全部節點 while(firstNode != NULL) { chainNode<T>* nextNode = firstNode->next; delete firstNode; firstNode = nextNode; } } //bool empty()const; //判斷鏈表是否爲空 template<class T> bool chain<T>::empty() const { return listSize == 0; } //int size() const; //記錄線性表元素個數 template<class T> int chain<T>::size() const { return listSize; } //T& get(int theIndex) const; //返回索引爲theIndex的元素 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; } //int indexOf(const T &theElement) const; //返回元素theElement的索引 template<class T> int chain<T>::indexOf(const T &theElemet) const { chainNode<T>* currentNode; currentNode = firstNode;int index=0; while(currentNode != NULL && currentNode->element != theElemet) { currentNode = currentNode->next; index++; } if(currentNode == NULL) return -1; else return index; } //void erase(int theIndex) const; //刪除索引爲theIndex的元素 //感受書上寫的代碼比個人更加簡潔一些 template<class T> void chain<T>::erase(int theIndex) const { checkIndex(theIndex); chainNode<T>* currentNode = firstNode;int index = 0; //若是刪除的元素是首元素,索引爲0,單獨處理 if(theIndex == 0) { currentNode = firstNode; firstNode = firstNode->next; }else { while((index) != (theIndex-1)) { currentNode = currentNode->next; index++; } currentNode->next = currentNode->next->next; } } //void insert(int theIndex, const T &theElement) const; //在索引爲theIndex的位置插入元素 //書上的寫法更加簡潔 template<class T> void chain<T>::insert(int theIndex,const T& theElement) const { checkIndex(theIndex); if(theIndex == 0) { theElement->next = firstNode->next; theElement = firstNode; } else { chainNode<T>* currentNode = firstNode; for(int i = 0;i<(theIndex-1);i++) currentNode = currentNode->next; theElement->next = currentNode->next->next; currentNode->next = theElement; } } //void output(ostream &out) const; //把線性表插入輸出流out 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; } //void checkIndex(int theIndex) const; //檢查索引是否有效 template<class T> void chain<T>::checkIndex(int theIndex) const { if(theIndex < 0 || theIndex > listSize) cout<<"輸入的索引不合法!"<<endl; return; }
下面是書上寫的某些函數的具體實現,我認爲書上的代碼更加簡潔,比我寫的邏輯更加清晰,能夠借鑑一下:索引
/* * 刪除索引爲theIndex的元素 */ template<class T> void chain<T>::erase(int theIndex) { //檢查索引是否合法 checkIndex(theIndex); //索引有效,刪除索引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; } /* * 插入元素theElement並使其索引爲theIndex */ 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 -1;i++) p = p->next; //在p以後插入 p->next = new chainNode<T>(theElement,p->next); } listSize++; }