链表的模板实现

        首先建立一个链表,需要注意的是用模板来写类的时候,必须将类定义和类声明都放在头文件里面,这个问题以前发邮件请教过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;
}

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

面向对象程序设计课程作业 1. 请创建一个数据类型为T的链表类模板List实现以下成员函数: 1) 默认构造函数List(),将该链表初始化为一个空链表(10分) 2) 拷贝构造函数List(const List& list),根据一个给定的链表构造当前链表(10分) 3) 析构函数~List(),释放链表中的所有节点(10分) 4) Push_back(T e)函数,往链表最末尾插入一个元素为e的节点(10分) 5) operator<<()友元函数,将链表的所有元素按顺序输出(10分) 6) operator=()函数,实现两个链表的赋值操作(10分) 7) operator+()函数,实现两个链表的连接,A=B+C(10分) 2. 请编写main函数,测试该类模板的正确性: 1) 用List模板定义一个List类型的模板类对象int_listB,从键盘读入m个整数,调用Push_back函数将这m个整数依次插入到该链表中;(4分) 2) 用List模板定义一个List类型的模板类对象int_listC,从键盘读入n个整数,调用Push_back函数将这n个整数依次插入到该链表中;(4分) 3) 用List模板定义一个List类型的模板类对象int_listA,调用List的成员函数实现A = B + C;(4分) 4) 用cout直接输出int_listA的所有元素(3分) 5) 用List模板定义List类型的模板类对象double_listA, double_listB, double_listC,重复上述操作。(15分) 3. 输入输出样例: 1) 输入样例 4 12 23 34 45 3 56 67 78 3 1.2 2.3 3.4 4 4.5 5.6 6.7 7.8 2) 输出样例 12 23 34 45 56 67 78 1.2 2.3 3.4 4.5 5.6 6.7 7.8
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值