链表的模板实现

来源:互联网 发布:马加爵事件完整版知乎 编辑:程序博客网 时间:2024/06/06 06:39

        首先建立一个链表,需要注意的是用模板来写类的时候,必须将类定义和类声明都放在头文件里面,这个问题以前发邮件请教过Bjarne Stroustrup ,他说这是现代编译器的规定,但没具体解释。

        下面是链表的实现: 

//LinkList.h
#ifndef LINKLIST_H
#define LINKLIST_H
#include 
<iostream>

#ifndef NULL
#define NULL 0
#endif    //NULL

namespace robert
{
    
template
<class T> class LinkList;    //The previous declaration of class LinkList

template
<class T>
           std::ostream
& operator<<(std::ostream&,const LinkList<T>&);        //declaration of function <<

template
<class T> class LinkNode
{
           friend 
class LinkList<T>;
           friend std::ostream
& operator<< <T> (std::ostream&,const LinkList<T>&);
           LinkNode():next(NULL) {}
           T data;
           LinkNode
<T>* next;
};

template
<class T> class LinkList
{
public:
          LinkList();
          
~LinkList();
    
          
bool IsEmpty() const;
          
int Length() const;
          
bool Insert(const T&);    //Insert the data to the end of the LinkList
          bool Insert(const T&,int);    //Insert the data at the appointed position
          bool Delete(int,T&);        //Delete the data at the appointed position and get the data field to another parameter
          bool Find(int,T&const;        
          
bool Change(int,const T&);
    
          LinkList
<T>* Sort();        //Sort the List, the larger first
           friend std::ostream& operator<< <T> (std::ostream&,const LinkList<T>&);
    
private:
          LinkNode
<T>* head;
};

template
<class T> LinkList<T>::LinkList()
{
         head
=new LinkNode<T>;
}

template
<class T> LinkList<T>::~LinkList()
{
           LinkNode
<T>* temp;
           
while(head)
           {
                   temp
=head->next;
                  delete head;
                   head
=temp;
           }
}

template
<class T> bool LinkList<T>::IsEmpty() const
{
             
return head==0;
}

template
<class T> int LinkList<T>::Length() const
{
             LinkNode
<T>* temp=head->next;
             
int len=0;
             
while(temp)
             {
                         len
++;        
                         temp
=temp->next;
              }
             
return len;
}

template
<class T> bool LinkList<T>::Insert(const T& x)
{
                LinkNode
<T>* temp=head;
                
while(temp->next)
                {
                            temp
=temp->next;
                }
                LinkNode
<T>* t=new LinkNode<T>;
                 t
->data=x;
                 t
->next=NULL;
                 temp
->next=t;    
                 
return true;
}


template
<class T> std::ostream& operator<<(std::ostream& out,const LinkList<T>& t)
{
            LinkNode
<T>* temp=t.head->next;
            
for(;temp;temp=temp->next)
    
out<<temp->data<<" ";
            
out<<std::endl;
            
return out;
}

template
<class T> bool LinkList<T>::Find(int index,T& t) const
{    
    
if(index<0 || index>=this->Length())
        
return false;
    LinkNode
<T>* temp=head->next;
    
int i=0;
    
while(i<index && temp)
    {
        temp
=temp->next;
        i
++;
    }
    
if(temp)
    {
        t
=temp->data;
        
return true;
    }
    
else
        
return false;
}
    
template
<class T> bool LinkList<T>::Change(int index,const T& t)
{
    
if(index<0 || index>=this->Length())
        
return false;
    LinkNode
<T>* temp=head->next;
    
int i=0;
    
while(i<index && temp)
    {
        temp
=temp->next;
        i
++;
    }
    
if(temp)
    {
        temp
->data=t;
        
return true;
    }
    
else
        
return false;
}
        
template
<class T> bool LinkList<T>::Delete(int index,T& t)
{
    
if(index<0 || index>=this->Length())
        
return false;
    LinkNode
<T>* temp=head->next;
    
if(index==0)
        head
->next=temp->next;
    
else
    {
        LinkNode
<T>* q=temp;
        
for(int i=0;i<index-1;i++)
            q
=q->next;
        temp
=q->next;
        q
->next=temp->next;
    }
    t
=temp->data;
    delete temp;
    
return true;
}        

template
<class T> bool LinkList<T>::Insert(const T& t,int index)
{
    
if(index<0 || index>this->Length())
        
return false;    
    LinkNode
<T>* p=head;
    LinkNode
<T>* q=new LinkNode<T>;
    q
->data=t;
    
for(int i=0;i<index;i++)
        p
=p->next;        
    q
->next=p->next;
    p
->next=q;
    
return true;
}

template
<class T> LinkList<T>* LinkList<T>::Sort()
{
    LinkList
<T>* h=new LinkList<T>;
    
int len=this->Length();
    
for(int i=0;i<len;i++)
    {
        T t;
        
this->Find(i,t);
        
int j=0;
        LinkNode
<T>* p=h->head->next;
        
while(p && t<p->data)
        {
            p
=p->next;
            j
++;
        }
        h
->Insert(t,j);
    }
    
return h;
}


}    
//The end of the namespace robert

#endif    //LINKLIST_H

        实现多项式相加减,就可以直接使用上面的模板类了。使用运算符重载,这样就更直接了:

//Polynomial.h
#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H

#include 
"LinkList.h"
#include 
<iostream>

namespace robert
{
    
class Polynomial;

class Item
{
public:
    Item() {}
    Item(
int c,int e):coef(c),expo(e) {}
    Item(
const Item& i):coef(i.coef),expo(i.expo) {}
    
    
bool operator<(const Item&const;
    
bool operator>(const Item&const;
    
bool operator==(const Item&const;
    
const Item operator-() const;
    
const Item operator+(const Item&const;
    friend 
class Polynomial;
    friend std::ostream
& operator<<(std::ostream&,const Item&);
    
private:
    
int coef;
    
int expo;
};

bool Item::operator<(const Item& i) const
{
    
if(this->expo<i.expo)
        
return true;
    
else
        
return false;
}

bool Item::operator>(const Item& i) const
{
    
if(*this<i)
        
return false;
    
else
        
return true;
}

bool Item::operator==(const Item& i) const
{
    
if(this->expo==i.expo)
        
return true;
    
else
        
return false;
}

const Item Item::operator+(const Item& i) const
{
    
return Item(coef+i.coef,expo);
}

const Item Item::operator-() const
{
    
return Item(-coef,expo);
}

std::ostream
& operator<<(std::ostream& out,const Item& i)
{    
    
if(i.coef>=0)
        
out<<"+"<<i.coef<<"x^"<<i.expo;
    
else
        
out<<i.coef<<"x^"<<i.expo;    
    
return out;
}

class Polynomial
{
public:
    Polynomial(
int x[][2],int);
    Polynomial();
    Polynomial(
const Polynomial&);
    
    
bool Get(int,Item&const;
    
void Add(const Item&);
    
bool IsEmpty() const;
    
int Length() const;
    
    Polynomial
* operator+(const Polynomial&);
    Polynomial
* operator-(const Polynomial&);
    friend std::ostream
& operator<<(std::ostream&,const Polynomial&);
private:
    LinkList
<Item>* list;
    
int count;
};


Polynomial::Polynomial(
int x[][2],int size)
{
    list
=new LinkList<Item>;
    count
=size;
    
for(int i=0;i<size;i++)
    {
        Item t(x[i][
0],x[i][1]);
        list
->Insert(t);
    }
}

Polynomial::Polynomial()
{
    list
=new LinkList<Item>;
    count
=0;
}

Polynomial::Polynomial(
const Polynomial& p)
{
    list
=new LinkList<Item>;
    count
=p.count;
    
for(int i=0;i<count;i++)
    {
        Item t;
        p.list
->Find(i,t);
        
this->list->Insert(t);
    }
}

bool Polynomial::IsEmpty() const
{
    
return (count==0);
}

int Polynomial::Length() const
{
    
return count;
}

std::ostream
& operator<<(std::ostream& out,const Polynomial& p)
{
    
out<<*p.list;    
    
return out;
}

bool Polynomial::Get(int index,Item& t) const
{
    
if(index<0 || index>=count)
        
return false;
    
if(list->Find(index,t))
        
return true;
    
else
        
return false;
}

void Polynomial::Add(const Item& t)
{
    
if(count==0)
    {
        list
->Insert(t);
        count
++;
        
return;
    }
    
int index=0;
    Item s;
    list
->Find(index,s);
    
while(t<&& index<count)
    {
        index
++;
        list
->Find(index,s);
    }
    
if(t==s)
    {
        
if(t.coef+s.coef==0)
            list
->Delete(index,s);
        
else
            list
->Change(index,t+s);
    }
    
else
    {
        list
->Insert(t,index);
        count
++;
    }
}

Polynomial
* Polynomial::operator+(const Polynomial& p)
{
    Polynomial
* q=new Polynomial;
    
for(int i=0;i<this->count;i++)
    {
        Item t;
        
this->Get(i,t);
        q
->Add(t);
    }
    
for(int i=0;i<p.count;i++)
    {
        Item t;
        p.Get(i,t);
        q
->Add(t);
    } 
    
return q;
}

Polynomial
* Polynomial::operator-(const Polynomial& p)
{
    Polynomial
* q=new Polynomial;
    
for(int i=0;i<this->count;i++)
    {
        Item t;
        
this->Get(i,t);
        q
->Add(t);
    }
    
for(int i=0;i<p.count;i++)
    {
        Item t;
        p.Get(i,t);
        q
->Add(-t);
    } 
    
return q;
}

}    
//The end of namespace robert

#endif    //POLYNOMIAL_H

       下面是测试程序:

//The Test File
#include "LinkList.h"
#include 
"Polynomial.h"
#include 
<iostream>
using namespace std;
using robert::LinkList;
using robert::Polynomial;
using robert::Item;

int main()
{
    LinkList
<int> t;
    t.Insert(
3),t.Insert(4);
    cout
<<t.Length()<<endl;
    cout
<<"t = "<<t;
    t.Insert(
5,1);    
    
int s=0;
    
if(t.Find(0,s))
        cout
<<"s = "<<s<<endl;
    t.Insert(
12),t.Insert(6);
    cout
<<"t = "<<t;
    t.Delete(
1,s);
    cout
<<s<<endl;
    cout
<<t;
    t.Insert(
2,0);
    t.Insert(
10,3);
    t.Insert(
9);t.Insert(20,0);    
    t.Insert(
32,2);
    cout
<<t;
    s
=14;
    t.Change(
2,s);
    cout
<<t;
    LinkList
<int> *c=t.Sort();
    cout
<<*c;
    cout
<<"---------------------------------------------"<<endl;
    
int a[][2]={{3,10},{5,4},{-3,2},{7,1},{-4,0}};
    Polynomial
* k1=new Polynomial(a,5);
    cout
<<"k1 : "<<*k1;    
    
int b[][2]={{7,7},{5,4},{-4,3},{2,0}};
    Polynomial
* k2=new Polynomial(b,4);
    cout
<<"k2 : "<<*k2;
    Polynomial
* k3=new Polynomial;
    k3
=*k1+*k2;
    cout
<<"k3 = k1 + k2 = "<<*k3;
    Polynomial
* k4=new Polynomial;
    k4
=*k1-*k2;
    cout
<<"k4 = k1 - k2 = "<<*k4;
}

             这里的程序我没怎么优化,就直接帖上来了。

原创粉丝点击