首先,同顺序表类相似,先建立线性表基类linear list方便以后使用,具体可详见我的上一篇文章:线性表类的建立。
为什么要建立链表类?
线性表类存在缺点:1、在表中插入或删除元素时,为了保证其他元素相对次序不变,平均需要移动一半元素,效率很低;2、要求占用连续空间,难以确定合适的存储空间大小,造成空间不够或者浪费的情况。而链表通过指针将元素相连,内存占用分散,且能有效节省存储和删除时间。
因此,下附代码:(其中用到了struct定义的LinkNode类,使得可以直接被linklist使用而不被外界直接访问)利用指针之间的关系,有以下代码:
#ifndef LLINEARLIST_H_INCLUDED
#define LLINEARLIST_H_INCLUDED
#include<iostream>
#include"linearlist.h"
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>
struct linkList:public Linearlist<T>{
protected:
LinkNode<T>* first;
public:
linkList(){first = new LinkNode<T>;}
linkList(linkList<T>&);
~linkList(){makeEmpty();}
void makeEmpty();
int Size() const{return 0;}
int Length() const;
int Search(T&) const;
int Locate(int ) const;
bool getData(int,T&) const;
bool setData(int,T&);
bool Insert(int,T&);
bool Remove(int,T&);
bool IsEmpty() const {return first->link==NULL;}
LinkNode<T>* locate(int) const;
LinkNode<T>* search(T&) const;
LinkNode<T>* getHead() const{
return first;
}
bool IsFull() const{return false;}
bool Append(const T& x);
int operator = (linkList<T>&);
template<class W>
friend istream& operator >> (istream&,linkList<W>&);
template<class W>
friend ostream& operator << (ostream&,linkList<W>&);
};
template<class T>
linkList<T>::linkList(linkList <T>& L){
T value;
LinkNode <T>* srcptr = L.getHead();
LinkNode <T>* desptr;
first = new LinkNode <T>;
desptr = first;
while (srcptr ->link != NULL){
value = srcptr ->link->data;
desptr ->link = new LinkNode <T>(value);
desptr = desptr ->link;
srcptr = srcptr ->link;
}
desptr ->link = NULL;
}
template <class T>
void
linkList <T>::makeEmpty(){
LinkNode <T>* p;
while(first ->link != NULL){
p = first ->link;
first ->link = p->link;
delete p;
}
}
template <class T>
int
linkList <T>::Length()const{
int n=0;
LinkNode <T>* p = first ->link;
while(p != NULL){
n++;
p=p->link;
}
return n;
}
template <class T>
int
linkList <T>::Search(T& item) const{
int n=1;
LinkNode <T>* p=first ->link;
while(p != NULL){
if (p->data == item) return n;
else{
p = p->link;
n++;}
}
return 0;
}
template <class T>
LinkNode <T>*
linkList <T>::search(T& item) const{
LinkNode <T>* p=first ->link;
while(p != NULL){
if (p->data == item)
break;
p = p->link;
}
return p;
}
template <class T>
int
linkList <T>::Locate(int i) const{
if (i<0 && i<=Length())
return i;
else
return 0;
}
template <class T>
LinkNode <T>*
linkList <T>::locate(int i) const{
int j;
LinkNode <T>* p=first;
if (!(i<0)){
for(j=0; j<i; j++){
if (!p) return NULL;
p = p->link;
}
return p;
}
return NULL;
}
template <class T>
bool
linkList <T>::getData(int i, T& x) const{
LinkNode <T>* lnptr = locate(i);
if (lnptr){
x=lnptr ->data;
return true;
}
return false;
}
template <class T>
bool
linkList <T>::setData(int i, T& x){
LinkNode <T>* lnptr = locate(i);
if (lnptr){
lnptr ->data = x;
return true;
}
return false;
}
template <class T>
bool
linkList <T>::Insert(int i, T& x){
LinkNode <T>* ptr = locate(i);
if (ptr){
LinkNode <T>* newnode = new LinkNode <T>(x);
newnode ->link = ptr->link;
ptr->link = newnode;
return true; }
return false;
}
template <class T>
bool
linkList <T>::Remove(int i, T& x){
LinkNode <T>* ptr;
if(i>0 && !(i>Length())) ptr = locate(i-1);
else return false;
if(ptr){
LinkNode <T>* wptr = ptr->link;
x = wptr->data;
ptr->link = wptr->link;
delete wptr;
return true; }
return false;
}
template <class T>
int
linkList <T>::operator = (linkList <T>& L){
T value;
LinkNode <T>* srcptr = L.getHead();
makeEmpty();
LinkNode <T>* desptr;
first = new LinkNode <T>;
desptr = first;
while (srcptr ->link != NULL){
value = srcptr ->link->data;
desptr ->link = new LinkNode <T>(value);
desptr = desptr ->link;
srcptr = srcptr ->link;
}
desptr ->link = NULL;
return 1;
}
template <class T>
bool
linkList <T>::Append(const T& x){
LinkNode <T>* ptr = first;
while(ptr->link) ptr = ptr->link;
LinkNode <T>* newnode = new LinkNode <T>(x);
if (!newnode){
cerr << "Memory allocation ERROR!" << endl;
return false;
}
newnode ->link = ptr->link;
ptr->link = newnode;
return true;
}
template <class W>
istream&
operator >> (istream & in, linkList <W>& L){
int n, x;
while (1) {
cout << "Please input the length of the list..." << endl;
in >> n;
if (n>0) break;
}
cout << "Please input the elements of the list one by one..." << endl;
for (int i=0; i<n; i++){
in >> x;
if (!L.Append(x)) break;
}
return in;
}
template <class W>
ostream &
operator << (ostream& out, linkList <W>& L){
LinkNode <W>* desptr = L.first ->link;
out << "The list has " << L.Length() << " element(s):" << endl;
while(desptr){
out << desptr ->data << ' ';
desptr = desptr ->link;
}
out << endl;
return out;
}
#endif // LLINEARLIST_H_INCLUDED
若有问题,恳请指正!