类的具体实现如下:
///////////////////////// #include"LinearList.h" #include <iostream> #include <cstdlib> using namespace std; template<class T> struct LinkNode //链表节点类 { T data; LinkNode<T>* link; LinkNode(LinkNode<T>* ptr=NULL):link(ptr){} LinkNode(const T& item,LinkNode<T>* ptr=NULL):data(item),link(ptr){} }; template<class T> class List //class List:public LinearList<T> 使用继承,有诸多问题 { protected: LinkNode<T>* first; public: List():first(new LinkNode<T>){} List(const T& item):first(new LinkNode<T>(item)){} List(const List& L); ~List(){makeEmpty();delete first;} void makeEmpty(); //新增成员 int Size()const{return 0;} //空实现,这里没有实际意义 int Length()const; LinkNode<T>* getHead()const{return first;} //新增成员 LinkNode<T>* Search(T& x)const; //这2个与基类相比,返回值不同.不能进行覆盖。说明在继承类中,若基类函数和继承类函数的返回值不同,视为不同的函数,不能同名覆盖,相当于重载 LinkNode<T>* Locate(int i)const; bool getData(int i,T& x)const; void setData(int i,T& x); bool Insert(int i,T& x); bool Remove(int i,T& x); bool IsEmpty()const{return (first->link==NULL)?true:false;} bool IsFull()const{return false;} void Sort(){}; //未实现 void output(); void inputFront(T endTag); void inputRear(T endTag); List<T>& operator=(const List<T>& L); }; template<class T> List<T>::List(const List& L) { LinkNode<T>* src=L.first->link; LinkNode<T>* dest=first=new LinkNode<T>; while(src!=NULL){ dest->link=new LinkNode<T>(src->data); dest=dest->link; src=src->link; } //dest->link=NULL; } template<class T> List<T>& List<T>::operator=(const List<T>& L) { LinkNode<T>* src=L.first->link; LinkNode<T>* dest=first=new LinkNode<T>; while(src!=NULL){ dest->link=new LinkNode<T>(src->data); dest=dest->link; src=src->link; } //dest->link=NULL; return *this; } template<class T> void List<T>::makeEmpty()//删除了除头结点以外的所有节点,有头结点内存泄露的问题 { LinkNode<T>* del; while(first->link!=NULL){ del=first->link; first->link=del->link; delete del; } } template<class T> int List<T>::Length()const { int count=0; LinkNode<T>* current=first->link; while(current!=NULL){ ++count; current=current->link; } return count; } template<class T> LinkNode<T>* List<T>::Search(T& x)const { LinkNode<T>* current=first->link; while(current!=NULL&¤t->data!=x){ current=current->link; } return current; } template<class T> LinkNode<T>* List<T>::Locate(int i)const { LinkNode<T>* current=first->link; if(i<1||i>Length()){ cerr<<"err"<<endl; exit(1); } int k=1; while(current!=NULL&&k<i){ current=current->link; ++k; } return current; } template<class T> bool List<T>::getData(int i,T& x)const { if(i<1||i>Length()){ cerr<<"err"<<endl; exit(1); } LinkNode<T>* current=Locate(i); if(current!=NULL){ x=current->data; return true; }else{ return false; } } template<class T> void List<T>::setData(int i,T& x) { if(i<1||i>Length()){ cerr<<"err"<<endl; exit(1); } LinkNode<T>* current=Locate(i); if(current!=NULL){ current->data=x; }else{ cerr<<"err"<<endl; exit(1); } } template<class T> bool List<T>::Insert(int i,T& x) { LinkNode<T>* current=first; if(i<0||i>Length()){ cerr<<"err"<<endl; exit(1); } int k=0; while(current!=NULL&&k<i){ ++k; current=current->link; } LinkNode<T>* newNode=new LinkNode<T>(x); if(newNode==NULL){ cerr<<"err"<<endl; exit(1); } newNode->link=current->link; current->link=newNode; return true; } template<class T> bool List<T>::Remove(int i,T& x) { LinkNode<T> *current=first,*del; if(i<=0||i>Length()){ cerr<<"err"<<endl; exit(1); } int k=0; while(current!=NULL&&k<i-1){ ++k; current=current->link; } del=current->link; current->link=del->link; x=del->data; delete del; return true; } template<class T> void List<T>::output() { LinkNode<T>* current=first->link; while(current!=NULL){ cout<<"# :"<<current->data<<" "; current=current->link; } cout<<endl; } template<class T> void List<T>::inputFront(T endTag) { LinkNode<T>* newNode; T val; makeEmpty(); cin>>val; while(val!=endTag){ newNode=new LinkNode<T>(val); if(newNode==NULL){cerr<<"err"<<endl;exit(1);} newNode->link=first->link; first->link=newNode; cin>>val; } } template<class T> void List<T>::inputRear(T endTag) { LinkNode<T> *newNode,*last; T val; makeEmpty(); last=first; cin>>val; while(val!=endTag){ newNode=new LinkNode<T>(val); if(newNode==NULL){cerr<<"err"<<endl;exit(1);} newNode->link=last->link; last->link=newNode; last=newNode; cin>>val; } }
测试程序如下:
int main(int argc, char* argv[]) { int val1=10; List<int> L1; List<int> L2(val1); cout<<"getHead(): "<<L1.getHead()->data<<endl; cout<<"getHead(): "<<L2.getHead()->data<<endl; int endTag=-1; L1.inputRear(endTag); L1.output(); cout<<"Length(): "<<L1.Length()<<endl; int data=111,data1; LinkNode<int>* ptr=L1.Locate(2); cout<<"Locate: "<<ptr->data<<endl; L1.setData(2,data); L1.getData(2,data1); cout<<"getData(): "<<data1<<endl; int val2=3; ptr=L1.Search(val2); cout<<"Search(): "<<ptr->data<<endl; int data3=33; L1.Remove(3,val2); L1.Insert(3,data3); L1.output(); List<int> L3(L1); L3.output(); List<int> L4; L4=L1; L4.output(); //L2.inputFront(endTag); // L2.output(); //L2.makeEmpty(); //L2.output(); system("pause"); return 0; }
测试结果如下:
getHead(): -842150451
getHead(): 10
1 2 3 4 5 6 7 8 9 -1
# :1 # :2 # :3 # :4 # :5 # :6 # :7 # :8 # :9
Length(): 9
Locate: 2
getData(): 111
Search(): 3
# :1 # :111 # :4 # :33 # :5 # :6 # :7 # :8 # :9
# :1 # :111 # :4 # :33 # :5 # :6 # :7 # :8 # :9
# :1 # :111 # :4 # :33 # :5 # :6 # :7 # :8 # :9
请按任意键继续. . .
注意事项:
1。采用附加头结点的单链表的实现方法。可以统一插入和删除操作,从而不用区分是否是在第一个节点(或者空表)或者是其他位置处插入或者删除。
2.可以采用继承LinearList基类的方法生成派生类,但是实现比较复杂,没有必要。因为要完全覆盖基类纯虚函数的接口。
3.在继承体系结构中,即使只有返回值不同。也当作不同的函数,是不能同名覆盖的,相当于函数的重载。
4.遍历链表是要用一个current指针来遍历,让他指向不同的节点。如果有两个链表至少需要定义两个这样的指针来遍历。
5.删除节点时,需要用del指针保存要删除的节点,最后在删除。删除时当前指正指向前一个节点,插入时当期指针指向要插入的位置。
6.写程序时多画图,想清楚了在动手。可以适当举例验证。
时间: 2024-10-26 17:49:01