c++类模板实现单项循环链表(带测试代码)

本文介绍了一个使用C++模板实现的循环链表数据结构,包括链表的基本操作如插入、删除、查找等,并提供了完整的代码示例。通过具体实例展示了如何创建、维护和操作循环链表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<iostream>
using namespace std;
template <class T>
struct CircLinkNode
{//链表节点定义 
    T data;
    CircLinkNode<T>*link;
    CircLinkNode(CircLinkNode<T>*next=NULL):link(next){
    }//初始化指针成员的构造函数 
    CircLinkNode(T d,CircLinkNode<T>*next=NULL):data(d),link(next){
    }//初始化指针成员和数据的构造函数     
};
template <class T>
class CircList
{
    public:
        CircList(const T&x)//构造函数
        {
            first=new CircLinkNode<T>(x);
            if(first==NULL)
            {
                cerr<<"储存分配失败"<<endl;
                return ;                                                    //这要是没有会不会有影响 
            }
            first->link=first;
        }
        CircList(CircList<T>&L) ;//复制构造函数
        void makeEmpty();
        ~CircList() //析构函数
        {
           makeEmpty();
           delete first;
        }
        int Length() ;//计算循环链表长度
        bool IsEmpty() 
        {
            return first==first->link;//头结点的下一结点是否为空 
         } 
         CircLinkNode<T>*getHead()const
         {
             return first;
         }
         void setHead(CircLinkNode<T>*p)
         {
             first=p;
         }
         CircLinkNode<T>*Search(T x) ;//搜索含x的元素
         CircLinkNode<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个元素,返回该元素的值
         void output();
         private:
         CircLinkNode<T>*first; 
 } ;
 template <class T>
 void CircList<T>::makeEmpty()
 {
     CircLinkNode<T>*temp,*p=first->link;;
     while(p!=first) 
     {
         temp=p->link;
         delete p;
         p=temp;
     }
     first->link=first;
 }
//置空函数思路 
//建立工作指针
//创建循环结束条件
//工作指针从头结点开始出发,摘结点,最后删除摘得的结点 
 template <class T>
 CircList<T>::CircList(CircList<T>&L) 
 {
     T value;
     CircList<T>*srcptr=L.getHead;//附加头地址
     CircList<T>*desptr=first=new CircList<T>;
     while(srcptr->link!=first)                      //判断条件发生变化 
     {
         value=srcptr->link->data;
         desptr->link=new CircList<T> (value);
          desptr=desptr->link;
          srcptr=srcptr->link;
     }
 };
 //复制构造函数思路
 //将链表赋值给另一个链表 
  template <class T>
  int  CircList<T>::Length()
  {
      CircLinkNode<T>*p=first->link;//从刚开始
      int count=0;
      while(p!=first) 
      {
          p=p->link;
          count++;
      }
      return count;
  };
//先从头开始
//初始化计数变量
//循环链表,终止条件为当前位置不是头节点)
//遍历完成后返回计数值
 template <class T>
CircLinkNode<T>*CircList<T>::Search(T x)
  {
       CircLinkNode <T>*current=first->link;//从头开始找
    while(current->link!=first) 
    {
        if(current->data==x)
        {
            cout<<"该元素存在于单链表中"<<endl;
            break; 
        }
        else
        {
            current=current->link;//后移 
         } 
         
        
    }     
             cout<<"不存在该元素!"<<endl;
         return NULL;

  };
  template <class T>
  CircLinkNode<T>*CircList<T>::Locate(int i) 
  {
       if(i<0)                                      
       {
           return NULL;
       }
       CircLinkNode<T>*current=first;
       int k=0;
       while(current!=NULL&&k<i)//超出判断 
       {
           k++;
           current=current->link;//指针移动 
       }
       return current; 

  };
  template<class T>
    T*CircList<T>::getData(int i)
    {
        if(i<0)
        {
            return NULL;
        }
        CircLinkNode<T>*current=Locate(i);//定位
        if(current==NULL) 
        return NULL;
        else 
        {
            cout<<"该位置的值为"<<current->data<<endl;
        return &current->data;//取出数值 
    }
        
    };
template<class T>//对第I个1位置进行赋值的函数 
    void CircList<T>::setData(int i,T&x) 
    {
        if(i>Length())
        {
            i=i%Length();
        }
        if(i<=0)
        {
                 cout<<"错误!"<<endl;                                                                                   //return NULL
        }
        CircLinkNode<T>*current=Locate(i) ;
        if(current==NULL)
        cout<<"错误!"<<endl;                                                                             //return NULL 
        else
        current->data=x;
        
     } ;
template<class T>
   bool CircList<T>::Insert(int i,T&x) //将x元素插入到第i位之后 
   {

        CircLinkNode<T>*current=Locate(i);                                                //怎么这里不严谨了不检查了,我就很奇怪 
       //设置查找指针
       CircLinkNode<T>*newNode=new CircLinkNode<T>(x) ;
       if(newNode==NULL)
       {
           cerr<<"储存分配错误!" <<endl;
           exit(1);//退出程序 
       }
       newNode->link=current->link;
       current->link=newNode;
       return true;// x先下后上 
   }; 
     template <class T> 
   bool CircList<T>::Remove(int i,T&x)
   {
                                                           
        CircLinkNode<T>*current=Locate(i-1)    ;//删除i位置,首先要找到它前面的位置
        if(current==NULL||current->link==NULL)    
        {
            return false;                                    }
           CircLinkNode<T>*del=current->link;//摘下删除节点 
            current->link=del->link;
            x=del->data;
            cout<<"删除的元素为"<<x<<endl;
            delete del;
            return true;                                             
   };
   template<class T>
   void CircList<T>::output() 
   {
   CircLinkNode<T>*current=first->link;
     while(current!=first)
      {
         cout<<current->data<<" ";
         current=current->link;//移动
  }
   };
   int main()
   {
       
           cout<<"-----------------创建链表-----------------"<<endl; 
           CircList<int>cli(0);
           int n;
           cout<<"请输入循环链表的长度";
           cin>>n;
           int a[1001];//可修改 
           cout<<"请输入链表的各个元素"; 
           for(int i=1;i<=n;i++)
           {
               cin>>a[i];
               cli.Insert(i,a[i]);
               
           }
           cout<<"------------创建链表成功!-----------"<<endl; 
           cli.output();
           cout<<"循环链表长度"<<cli.Length()<<endl;
           cout<<"插入i位置之后以及元素" <<endl;
           int i1;
           int x1;
           cin>>i1>>x1;
           if(i1>cli.Length());
           i1=i1%cli.Length();
           cli.Insert(i1,x1);
           cout<<"插入元素后的链表为" <<endl;
           cli.output();
           cout<<"链表长度为" <<cli.Length()<<endl;
           cout<<"请输入需要删除的位置"<<endl;
           int i2;
           cin>>i2;
           if(i2>cli.Length());
           i2=i2%cli.Length();
           int x2;
           cli.Remove(i2,x2);
           cout<<"删除后的链表为" <<endl;
           cli.output();
           cout<<"请输入要取的元素位置"<<endl;
           int i3;
           cin>>i3;
           cli.getData(i3);
           cout<<"请输入要修改的位置及要修改后的元素" <<endl;
           int i4,x4;
           cin>>i4>>x4;
           cli.setData(i4,x4);
           cout<<"修改后的链表为"<<endl;
           cli.output(); 
       return 0;
   }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值