自己写的一个单链表模版,模版的实现和定义是不可以分开两个文件写的 和平时写的类的不太一样 这个要注意,一开始没注意到这个 就出现了那个最讨厌的 unresolve external symbol 的错误 下面是代码 功能是一些比较常见的功能
这个是经过修改完善后的一个最终版本,以后有新想法 会再添加进去
mylist.h文件
#include<iostream.h> template<class T> class My_list; template<class T> class Node //节点类 { private: T data; Node<T> *next; public: Node() { next=NULL; } Node(T d) { data=d; next=NULL; } friend My_list<T>;//声明为友元,在链表类中访问节点类的私有成员 }; template<class T> class My_list { private: Node<T> *head,*tail; static bool flag;//判断是否已经排序的标志 public: My_list() { head=tail=new Node<T>(); } ~My_list() { clean(); delete head; cout<<"析构函数~"<<endl; } Node<T> *create(T d)//创建节点 { Node<T> *p=new Node<T>(d); return p; } void insert_front(Node<T> *p)//头插入 { p->next=head->next; head->next=p; } void insert_rear(Node<T> *p)//尾插入 { tail->next=p; tail=p; } bool empty()//判断链表是否为空 { return (head->next==0); } int length()//计算表长 { int size=0; Node<T> *p=head->next; while(p) { size++; p=p->next; } return size; } bool retrive(int k, T& x)//由x来返回k位置处的值 { int pos=1; Node<T> *p=head->next; while(pos<k && p) { pos++; p=p->next; } if(!p && pos<=k) return false; else { x=p->data; return true; } } int locate(const T& x)//返回x在表中位置,找不到返回0 { int pos=1; Node<T> *p=head->next; while(p->data!=x && p->next) { p=p->next; pos++; } if(!p || p->data!=x) pos=0; return pos; } bool insert(int k,T x)//在k位置后面插入x { if(k<0 || k>length()) return false; int i=1; Node<T> *p=head->next; Node<T> *temp=new Node<T>(x); if(k==0)//插在头结点之后 { temp->next=head->next; head->next=temp; } else { while(i<k && p) { i++; p=p->next; } temp->next=p->next; p->next=temp; } return true; } bool erase(int k,T& x)//删除k位置的节点,将k处的值给x { int i=1; Node<T> *p=head->next; if(k==1) { head->next=p->next; x=p->data; delete p; return true; } while(i<k-1 && p) { i++; p=p->next; } if(!p->next && i<=k-1) return false; else { Node<T> *temp=p->next;//temp指向k处节点 p->next=temp->next; x=temp->data; delete temp; return true; } } void print_list() const//输出表 { Node<T> *p=head->next; if(!p) { cout<<"List is empty."<<endl; return ; } while(p) { cout<<p->data<<'\t'; p=p->next; } cout<<endl; } void clean()//删除整条链,表头结点在,那个由析构函数回收 { Node<T> *p=head->next; while(p) { head->next=p->next; delete p; p=head->next; } } void select_sort()//用选择排序进行排序按升序排列 { Node<T> *p,*q,*r; int t1,t2; p=head->next; while(p) { t1=p->data; q=p->next; while(q) { if(t1>q->data) { t1=q->data; r=q; } q=q->next; } if(t1!=p->data) { t2=p->data; p->data=t1; r->data=t2; } p=p->next; } flag=true; } void unique()//删除值重复的节点 { if(!flag) select_sort(); Node<T> *p=head->next; while(p->next) { while(p->data==p->next->data) { Node<T> *q=p->next; p->next=q->next; delete q; } p=p->next; } } bool inverse()//逆置整条链 { Node<T> *p=head->next; Node<T> *tail=NULL,*r; while(p) { r=p->next; p->next=tail; tail=p; p=r; } head->next=tail; return true; } }; template<class T> bool My_list<T>::flag=false;
下面是一个测试代码 mian.cpp #include"mylist.h" int main() { My_list<int> list; if(list.empty()) cout<<"list is empty"<<endl; Node<int> *p; int x; while((cin>>x) && (x!=0)) { p=list.create(x); list.insert_rear(p); } list.print_list(); p=list.create(9); list.insert_front(p); list.print_list(); cout<<"表长为:"<<list.length()<<endl; int pos; cout<<"输入要返回哪个位置:"; cin>>pos; if(list.retrive(pos,x)) cout<<x<<endl; int t,xx; cout<<"输入要返回哪个值的位置:"; cin>>t; xx=list.locate(t); if(xx) cout<<xx<<endl; else cout<<"No find"<<endl; cout<<"输入要插入数字的位置和数值"<<endl; cout<<"位置:"; cin>>pos; cout<<"值:"; cin>>t; if(list.insert(pos,t)) cout<<"insert is successful."<<endl; else cout<<"insert is fail."<<endl; list.print_list(); int tt; cout<<"输入要删除的位置:"; cin>>pos; if(list.erase(pos,tt)) cout<<tt<<endl; list.print_list(); list.select_sort(); list.print_list(); list.unique(); list.print_list(); cout<<"_______逆置_______"<<endl; if(list.inverse()) cout<<"逆置成功"<<endl; list.print_list(); cout<<"______清空表______"<<endl; list.clean(); if(list.empty()) cout<<"清空完成"<<endl; return 0; }