单链表的模板类(C++)
/*header.h*/
#pragma once #include<iostream> using namespace std; template<class T> struct LinkNode //节点类定义 { T data; //数据域 LinkNode<T> *next; //链指针域 LinkNode(LinkNode<T> *ptr = NULL){this->next = ptr;} //初始化指针域的构造函数 LinkNode(const T& item, LinkNode<T> *ptr = NULL)//初始化数据成员和指针成员和指针的构造函数 { this->data = item; this->next = ptr; } }; template<class T> class List //用头结点的数据域表示链表元素数量 { protected: LinkNode<T> *first; public: List(){first = new LinkNode<T>;first->data = 0;}//无参数构造 List(const T& x) { this->first = new LinkNode<T>; //first->data = 1; this->inputHead(x); }//含有参数的构造函数 List(List<T>& L);//拷贝构造 ~List(){makeEmpty();}//析构函数 void makeEmpty();//将链表置空的函数 int Length()const{return this->first->data;}//计算链表长度的函数 LinkNode<T>* getHead()const{return this->first;}//返回附加头结点地址 LinkNode<T>* getRear()const;//返回尾部指针 void inputHead(T head);//头插 void inputRear(T rear);//尾插 void output();//将链表打印出来 bool IsEmpty()const{return !this->first->data;} void Sort();//排序 bool Insert(int i, T& x);//在第i个位置插入x bool Remove(int i, T& x);//删除第i个元素,将第i个元素的data赋值给x T *getData(int i);//返回第i个元素的data地址 void setData(int i, T& x);//将第i个元素的data值更改为x LinkNode<T> *Search(T x);//查找链表中第一个含有data为x的元素,返回x节点指针 LinkNode<T> *Locate(int i);//返回第i个元素的指针 List<T>& operator=(List<T>& L);//符号重载,赋值 }; template<class T> List<T>& List<T>::operator=(List<T>& L) { if(!L.IsEmpty()) { LinkNode<T> *srcptr = L.first, *desptr = this->first; while(srcptr->next != NULL) { desptr->data = srcptr->data; desptr->next = new LinkNode<T>; srcptr = srcptr->next; desptr = desptr->next; } desptr->data = srcptr->data; }
return *this; } template<class T> LinkNode<T>* List<T>::Locate(int i)//找第i个元素,找到返回地址,找不到返回头结点地址 { if(i>0 && i<this->first->data) { int j = 0; LinkNode<T> *tmp = this->first; while(j!=i) { tmp = tmp->next; ++j; } return tmp; } return this->first; } template<class T> LinkNode<T>* List<T>::Search(T x) { if(!this->IsEmpty()) { LinkNode<T> *tmp = this->first->next; while(tmp->data!=x && tmp->next!=NULL) { tmp = tmp->next; } if(tmp->data==x) return tmp; } return this->first; } template<class T> void List<T>::setData(int i, T& x) { if(i>0 && i<=this->first->data) { int j = 0; LinkNode<T> *tmp = this->first; while(j!=i) { tmp = tmp->next; ++j; } tmp->data = x; } } template<class T> T* List<T>::getData(int i) { if(i>0 && i<=this->first->data) { LinkNode<T> *tmp = this->first; int j = 0; while(j!=i) { tmp = tmp->next; ++j; } return &tmp->data; } } template<class T> bool List<T>::Remove(int i, T& x) { if(i>0 && i<=this->first->data) { LinkNode<T> *tmp = this->first, *p; if(i!=1) { int j = 0; while(j!=i-1) { tmp = tmp->next; ++j; } p = tmp->next; tmp->next = p->next; x = p->data; delete p; } else { p = tmp->next; x = p->data; tmp->next = p->next; delete p; } --this->first->data; return true; } return false; } template<class T> bool List<T>::Insert(int i, T& x) { if(i>0 && i<this->first->data+2) { if(i == this->first->data+1) { this->inputRear(x); return true; } else if(i == 1) { this->inputHead(x); return true; } int j = i-1; LinkNode<T> *tmp = new LinkNode<T>, *p = this->first; tmp->data = x; while(j) { p = p->next; --j; } tmp->next = p->next; p->next = tmp; ++this->first->data; return true; } else return false; } template<class T> void List<T>::Sort()//排序有两类方法,一种是改变指针指向的,一种是仅为元素data排序,而不改变指针指向 { if(this->first->data > 1) { int i = this->first->data, j; LinkNode<T> *p = this->first, *q; while(i) { p = p->next; q = p->next; j = i - 1; while(j) { if(p->data > q->data) { p->data = p->data + q->data; q->data = p->data - q->data; p->data = p->data - q->data; q = q->next; } --j; } --i; } } } template<class T> void List<T>::inputHead(T head) { LinkNode<T> *tmp = new LinkNode<T>; if(tmp == NULL) { cerr<<"内存分配错误!\n"<<endl; exit(-1); } if(this->first->next != NULL) { tmp->next = this->first->next; this->first->next = tmp; } else { this->first->next = tmp; tmp->next = NULL; } tmp->data = head; ++this->first->data; } template<class T> void List<T>::inputRear(T rear) { LinkNode<T> *tmp = new LinkNode<T>; if(tmp == NULL) { cerr<<"内存分配错误!\n"<<endl; exit(-1); } LinkNode<T> *p = this->getRear(); p->next = tmp; tmp->data = rear; ++this->first->data; } template<class T> void List<T>::output() { LinkNode<T> *p = this->first->next; while(p!=NULL) { cout<<p->data<<"—>"; p = p->next; } cout<<"over"<<endl; } template<class T> List<T>::List(List<T>& L) { T value; LinkNode<T> *srcptr = L.getHead(); LinkNode<T> *desptr = this->first = new LinkNode<T>; this->first->data = srcptr->data; while(srcptr->next != NULL) { value = srcptr->next->data; desptr->next = new LinkNode<T>(value); desptr = desptr->next; srcptr = srcptr->next; } desptr->next = NULL; } template<class T> void List<T>::makeEmpty() { LinkNode<T> *p, *q = this->first->next; this->first->data = 0; while(q != NULL) { p = q; q = q->next; delete p; } } template<class T> LinkNode<T>* List<T>::getRear()const { LinkNode<T> *p = this->first; while(p->next!=NULL) p = p->next; return p; } /* template<class T> int List<T>::Length()const { LinkNode<T> *p = this->first->next; int count = 0; while(p != NULL) { ++count; p = p->next; } };*/
一个含有头结点的单链表,链表头节点的数据与保存链表长度。
顺序表适合随机读,链表适合随机写,随机删除。
/*main.cpp*/
#include"header.h"
int main()
{
const int o = 10;
List<int> L(0),M;
for(int i=100; i<=110; ++i)
L.inputHead(i);
//for(int i=0; i<=10; ++i)
// L.inputRear(i);
L.output();
int i = 2111;
L.Insert(1, i);
L.output();
L.Sort();
L.output();
L.Remove(1, i);
cout<<i<<endl;
L.output();
cout<<*L.getData(1)<<endl;i = 1;
L.setData(12, i);
L.output();
cout<<L.Search(100)<<endl;
M = L;
M.output();
return 0;
}
运行结果如下
不积小流无以成江河