单链表(c++类模板实现)

后续会写详细的实现过程,就是功能4,和功能13测试的时候还有点问题,不过会改进的

定义在“LinkedList.h”

#include <iostream>
using namespace std;
# ifndef INCLUDE_LINKEDLIST_H_
# define INCLUDE_LINKEDLIST_H_
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>
 class List{//单链表类定义,不用继承也可以实现 
 
     public:
          List() {
         first = new LinkNode<T>(0,NULL); 
     }
     List(const T&x) 
     {
         first=new LinkNode<T>(x) ;    //带参数的构造函数 
     }
     List(List<T>&L) ;//复制构造函数                                         语法 
     ~List() {
     makeEmpty(); //析构函数 
     
     }
     void makeEmpty();
     int Length()const;  
     LinkNode<T>*getHead()const                                        //类内定义的方式 
     {
     return first;                                                   //  为什么要用常函数     
     } 
     void setHead(LinkNode<T>*p) //设置附加头结点地址 
     {
         first=p;
     }
     LinkNode<T>*Search(T x) ;//搜索含数据x的元素 
     LinkNode<T>*Locate(int i);//搜索第i个元素的地址 
     T*getData(int i); //取出第i个元素的数值 
     void setData(int i,T&x);//用x修改i位置的数值 
     bool Insert(int i,T&x) ;//在第i个元素后插入x元素 
     bool Remove(int i,T&x) ;//删除第i个元素,x返回该元素的值 
     bool IsEmpty()const{                                                   //这里用常函数到底是用来干嘛的 
     //判断链表是否为空
      return first->link==NULL ?true:false; 
     }
     bool IsFull()const
     {
         return false;//                                                        好家伙,直接返回错误了,还判断个鬼啊 
     }
     void Sort();//排序函数 
     void createlist(T end);
     void output() ;//输出
    List<T>&operator=( List<T>&L) ;//重载函数,赋值 
    protected:
     LinkNode<T> *first; 
 };
  
  template <class T>//复制构造函数 
  List<T>::List(List<T>&L) 
  {
      T value;
      LinkNode<T>*srcptr=L.getHead;//被复制表的附加头结点地址
      LinkNode<T>*desptr=first=new LinkNode<T>;  
      while(srcptr->link!=NULL)//逐个节点复制
      {
          value=srcptr->link->data;
          desptr->link=new LinkNode<T> (value);
          desptr=desptr->link;
          srcptr=srcptr->link;
                 } 
  };
  template <class T>
  void List<T>::makeEmpty()//将链表置为空 
  {
      LinkNode<T>*q;  //建 
      while(first->link!=NULL) 
      {
          //当链表不为空时,删除节点
          q=first->link;//指 
          first->link=q->link;//摘
          delete q; //删 
      }
  }; 
  
  
  template <class T>
  int List<T>::Length()const//计算带附加节点的链表长度 
  {
      LinkNode<T>*p=first->link;//从头节点开始 
      int count=0;//计数 
      while(p!=NULL) 
      {
          p=p->link;//移动 
          count++;//计数 
      }
      return count; 
  }
   template<class T>
   LinkNode<T>*List<T>::Search(T x)                                  //有点不太清除这里的函数类型选择 
   {  
     
    LinkNode<T>*current=first->link;//从头开始找
    while(current!=NULL) 
    {
        if(current->data==x)
        {
            cout<<"该元素存在于单链表中"<<endl;
            break; 
        }
        else
        {
            current=current->link;//后移 
         } 
         
        
    }     
    
             cout<<"不存在该元素!"<<endl;
         return NULL;
   };
   template<class T>
   LinkNode<T>*List<T>::Locate(int i) //定位函数
   {
       //合理性判断
       if(i<0)                                       //总觉得这合理性少了点什么 
       {
           return NULL;
       }
       LinkNode<T>*current=first;
       int k=0;
       while(current!=NULL&&k<i)//超出判断 
       {
           k++;
           current=current->link;//指针移动 
       }
       return current; 
    } ;
    
    template<class T>
    T*List<T>::getData(int i)
    {
        if(i<0)
        {
            return NULL;
        }
        LinkNode<T>*current=Locate(i);//定位
        if(current==NULL) 
        return NULL;
        else 
        {
            cout<<current->data<<endl;
        return &current->data;//取出数值 
    }
        
    };
    template<class T>//对第I个1位置进行赋值的函数 
    void List<T>::setData(int i,T&x) 
    {
        if(i<=0)
        {
                 cout<<"错误!"<<endl;                                                                                   //return NULL
        }
        LinkNode<T>*current=Locate(i) ;
        if(current==NULL)
        cout<<"错误!"<<endl;                                                                             //return NULL 
        else
        current->data=x;
        
     } ;
   template<class T>
   bool List<T>::Insert(int i,T&x) //将x元素插入到第i位之后 
   {
        LinkNode<T>*current=Locate(i);                                                //怎么这里不严谨了不检查了,我就很奇怪 
       //设置查找指针
       if(current==NULL) 
       return false;
       LinkNode<T>*newNode=new LinkNode<T>(x) ;
       if(newNode==NULL)
       {
           cerr<<"储存分配错误!" <<endl;
           exit(1);//退出程序 
       }
       newNode->link=current->link;
       current->link=newNode;
       return true;// x先下后上 
   }; 
   template <class T> 
   bool List<T>::Remove(int i,T&x)
   {
                                                           //这也不用检查?!
        LinkNode<T>*current=Locate(i-1)    ;//删除i位置,首先要找到它前面的位置
        if(current==NULL||current->link==NULL)    
        {
            return false;                                    }
            LinkNode<T>*del=current->link;//摘下删除节点 
            current->link=del->link;
            x=del->data;
            delete del;
            return true;                                             
   };
   
   
   template<class T>
   void List<T>::Sort()                                //直接忽略了,你确定???什么鬼教材 
   {
          LinkNode<T>*p=first;
          for(int i=0;i<Length();i++)
          {
              p=Locate(1);
              for(int j=1;j<=Length()-i;j++)
              {
                  if(p->data>(p->link->data))
                  {
                      T n;
                      p->data=n;
                      n=p->link->data;
                      p->link->data=n;//冒泡排序法 
                      
                  }
                  p=p->link;//向后移动 
              }
              
          }
       cout<<"排序后的链表为" <<endl;
       while(p->link!=NULL)
       {
           cout<<p->data;
           p=p->link;
       }
          };
   template <class T>
   void List<T>::createlist( T end) 
   {
       LinkNode<T>*newNode;
       T val;
       first=new LinkNode<T>(0,NULL);
       if(first==NULL)
       {
           cerr<<"储存分配错误!" <<endl;
           exit(1);
       }
       cin>>val;
       while(val!=end)
       {
           newNode=new LinkNode<T>(val);
           if(newNode==NULL)
           {
               cerr<<"储存分配错误"<<endl;
               exit(1) ;
           }
           newNode->link=first->link;
           first->link=newNode;
           cin>>val;
       }
       
   };
   template<class T>
   void List<T>::output() 
   {
       LinkNode<T>*current=first->link;
       while(current!=NULL) 
       {
           cout<<current->data<<endl;
           current=current->link;//移动 
       }
   };
   template<class T>
  List<T>&List<T>::operator=( List<T> & L) 
   {
       //重载函数:赋值操作
       T value;
       LinkNode<T>*srcptr=L.getHead;//被复制表的附加头节点地址
       LinkNode<T>*destptr=first=new LinkNode<T>;
       while(srcptr->link!=NULL) 
       {
           //逐个节点复制
           value=srcptr->link->data;
           destptr->link=new LinkNode<T>(value) ;
           destptr=destptr->link;
           srcptr=srcptr->link;
       }
       destptr->link=NULL;
       return *this;//返回操作对象地址 
   };
   #endif
   

定义在.cpp文件中

#include <iostream>
#include"LinkedList.h"
typedef int T;
using namespace std;
int main()
   {
       cout<<"---------------------单链表------------------"<<endl;
       cout<<"请输入单链表的值并以0为结束标志"<<endl;
   List<int>susu;
   susu.createlist(0);
       cout<<"------------单链表已经创建成功----------------" <<endl;
    susu.output();
    cout<<"-------------请输入要执行的操作---------------"<<endl;
        cout<<"1:计算链表长度              2:将链表置为空             3:返回附加头结点的地址" <<endl;
    cout<<"4:设置附加头节点的地址      5:搜索是否含x元素           6:搜索含第i个元素的地址"<<endl;
    cout<<"7:取出第i个元素的值和地址          8:用x修改第i个元素的值     9:在第i个元素后插入元素x"<<endl;
    cout<<"10:删除第i个元素,返回该元素的值     11:判断是否为空表      12:判断是否为满表"<<endl;
    cout<<"13:对链表进行排序   14:输出当前链表的值"<<endl;
         

    int a;
    cin>>a;
    switch(a) 
    {
        case 1:
           cout<<susu.Length()<<endl;
           break;
           case 2:
               susu.makeEmpty();
               cout<<"置空成功"<<endl;
               break;
               case 3:
                   cout<<susu.getHead()<<endl;
                   break;
                   case 4:
                       cout<<"请输入附加头节点的地址"<<endl; 
                       LinkNode<T>*lo;
                       susu.setHead(lo);
                   break;
                   case 5:
                       int b;
                       cout<<"请输入元素x"<<endl;
                       cin>>b;
                       susu.Search(b) ;
                       break;
                       case    6:
                           cout<<"请输入要查询地址的元素"<<endl;
                           int c;
                           cin>>c;
                           susu.getData(c);
                           break;
                           case 7:
                               cout<<"请输入i"<<endl;
                               int d;
                               cin>>d;
                               cout<<susu.getData(d) <<endl;
                               break;
                        case 8:cout<<"请输入对应的x和i值" ;
                        int e;
                        T f;
                        cin>>e>>f;
                        susu.setData(e,f); 
                        cout<<"修改后的链表为"<<endl;
                        susu.output();
                        break;
                        case 9:
                            cout<<"请输入对应的i和x值"<<endl;
                            int g;
                            T h;
                            cin>>g>>h;
                            susu.Insert(g,h);
                            cout<<"插入后的链表为"<<endl;
                            susu.output();
                            break;
                            case 10:
                            cout<<"请输入对应的i" ;
                            int k;
                            T o;
                            cin>>k;
                            susu.Remove(k,o) ;
                            cout<<"删除的元素为"<<o<<endl;
                            
                            break;
                            case 11:
                            susu.IsEmpty();
                            if(susu.IsEmpty()!=0) 
                            {
                                cout<<"链表为空"; 
                            }
                            else
                            {
                                cout<<"链表非空"<<endl;
                            }
                            break; 
                            case 12:
                                susu.IsFull();
                                if(susu.IsFull()!=0) 
                            {
                                cout<<"链表已满"; 
                            }
                            else
                            {
                                cout<<"链表非满"<<endl;
                            }
                                break;
                                case 13:
                                susu.Sort();
                                break;
                                case 14:
                                    cout<<"当前链表的值为"<<endl;
                                    susu.output();
                                    break; }
    
         

                                     
    return 0;
}
 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值