双向循环链表C++实现

 

#ifndef YITERATOR_H_
#define YITERATOR_H_
template<class T>
//在外部自定义一个迭代器类
class yiterator
{
public:
              virtual void outputd(){ };

};
#endif /* YITERATOR_H_ */


#ifndef DCIRCULARLISTHEADER_H_
#define DCIRCULARLISTHEADER_H_
#include"yiterator.h"
#include "linearList.h"
 template <typename T>
struct chainNoded
{
   T element;
   chainNoded<T> *next;//指向下一个节点
   chainNoded<T>* pre;//指向前一个节点

   chainNoded() {next =NULL;
   pre = NULL;}
   chainNoded(const T& element){
	   this->element = element;
	   next =NULL;
	   pre = NULL;
   }
   chainNoded(const T& element, chainNoded* next,chainNoded* pre)
   {
	   this->element = element;
	   this->next = next;
	   this->pre = pre;
   }
};




template<class T>
class dcircularlistheader:public linearList<T>
{
   public:

	dcircularlistheader(int initialCapacity = 10);
      ~dcircularlistheader();
      bool empty() const {return listSize == 0;}//判断是否为空
      int size() const {return listSize;}//返回链表节点数
      T& get(int theIndex) const;// 按照索引返回元素值
      int indexOf(const T& theElement) const;//根据元素返回索引值
      void erase(int theIndex);//删除函数
      void insert(int theIndex, const T& theElement);//插入
      void output(std::ostream& out) const;//按序输出
      chainNoded<T>* first(){ return headerNode;}//返回头结点的值
      class iterator;
// 返回迭代器
   iterator* iteratord(chainNoded<T>* a){

              return new iterator(a);
           }


   protected:
        void checkIndex(int theIndex) const;
        chainNoded<T>* headerNode;
        int listSize;
   public:
        class iterator:public yiterator<T>
         {
          public:
           iterator(chainNoded<T>* theNode=NULL)
           { node=theNode;
           }
           T& operator*() const {return node->element;}//取值
           T* operator->() const{return &node->element;}

             iterator& operator++()
           {
            node=node->next;
            return *this;
           }
           iterator operator++(int)
                       	      {iterator old = *this;
                       	       node = node->next;
                       	       return old;
                       	      }

           iterator& operator--()
           {
            node=node->pre;
            return *this;
           }
           iterator operator--(int)
                                 	      {iterator old = *this;
                                 	       node = node->pre;
                                 	       return old;
                                 	      }
           bool operator!=(const iterator right)const
           {
            return node !=right.node;
           }
           bool operator==(const iterator right)const
           {
            return node==right.node;
           }
           iterator begin() const {return iterator(node->next);}//输出当前节点
             iterator end() const{return iterator(node->pre); }//输出当前节点的前一个节点
          //使用迭代器进行输出链表
             virtual   void outputd(){
             for(iterator iter=begin();iter!=++end();++iter)
               std::cout<<*iter<<" ";
              std::cout<<std::endl; }

          private:
            chainNoded<T>* node;
         };

};



#endif /* DCIRCULARLISTHEADER_H_ */ *  Created on: 2018年7月12日




#include "dcircularlistheader.h"


template<class T>
dcircularlistheader<T>::dcircularlistheader(int initialCapacity)
{if (initialCapacity < 1)
    throw std::invalid_argument("Initial capacity = " + std::to_string(initialCapacity) + " Must be > 0");
   headerNode = new chainNoded<T>();
   //令头结点起初指向他自己
   headerNode->pre = headerNode;
   headerNode->next = headerNode;
   listSize = 0;
}
template<class T>
dcircularlistheader<T>::~dcircularlistheader(){
	chainNoded<T>*q=headerNode;
	while (q->next!=headerNode )
	   {// delete firstNode
	      chainNoded<T>* nextNode = q->next;//保存下一个节点
	      delete q;//释放节点指向的空间
	      q = nextNode;
	   }
	delete headerNode;//最后删除头结点指向的空间
}
template<class T>
void dcircularlistheader<T>::checkIndex(int theIndex) const
{//检查索引值是否合法

   {if(theIndex < 0 || theIndex >=listSize){
		throw std::out_of_range("index = " + std::to_string(theIndex) + " size = " + std::to_string(listSize)); //C++11标准引入的
	}
   }

}


template<class T>
T& dcircularlistheader<T>::get(int theIndex) const
{
    checkIndex(theIndex);
    chainNoded<T>* currentNode = headerNode->next;//先令当前节点指向第一个节点
    for(int i = 0;i<theIndex;i++)//移动索引值次
    currentNode = currentNode->next;//移动指针
    return currentNode->element;//返回目标元素
}


template<class T>
int dcircularlistheader<T>::indexOf(const T& theElement) const
{

   chainNoded<T>* currentNode = headerNode->next;
   int index = 0;
   //根据条件移动指针
   while (currentNode->element != theElement&&currentNode!=headerNode)
   {

      currentNode = currentNode->next;
      index++;
   }

    //若最终移动到头结点则没找到
   if (currentNode == headerNode)
      return -1;
   else
      return index;
}


template<class T>
void dcircularlistheader<T>::erase(int theIndex)
{
    checkIndex(theIndex);
    chainNoded<T>*deleteNode;
    chainNoded<T>* p = headerNode;
       	for(int i = 0;i < theIndex;i++)//将指针移动到到目标节点的前一个节点
        p = p->next;
    deleteNode = p->next;//保存目标节点
    p->next->next->pre=p;//令目标节点的前驱等于目标节点的前驱
    p->next = p->next->next;//目标节点的后继等于目标节点的后继

    listSize--;// 链表大小减一
    delete deleteNode;
}


template<class T>
void dcircularlistheader<T>::insert(int theIndex, const T& theElement)
{
//判断是否合法
	if (theIndex != listSize)
		   checkIndex(theIndex);
//移动指针到待插入索引的前一个位置
   chainNoded<T>* p = headerNode;
   for (int i = 0; i < theIndex; i++)
      p = p->next;

     p->next = new chainNoded<T>(theElement, p->next,p);//插入新节点
     p->next->next->pre=p->next;//原位置节点指向新插入节点

   listSize++;//链表大小加一
}

template<class T>
void dcircularlistheader<T>::output(std::ostream& out) const
{
	 chainNoded<T> *p = headerNode->next;//指向第一个节点
	   out <<std::endl;
	   //一直循环输出每一个元素
	   while(p != headerNode){
		   out << p->element <<" ";
		   p = p->next;
	   }
	   out << std::endl;
//   for (chainNode<T>* currentNode = headerNode->next;
//                      currentNode != headerNode;
//                      currentNode = currentNode->next)
//      out << currentNode->element << "  ";
}
//对<<运算符进行重载
template <class T>
std::ostream& operator<<(std::ostream& out, const dcircularlistheader<T>& x)
   {x.output(out); return out;}
测试用例
1、对每个函数的测试数据
2、对程序整体的测试数据

#include <numeric>//accumulate
#include <algorithm>
#include"dcircularlistheader.cpp"
using std::cout;
using std::endl;



int main()
{
   // test constructor
	dcircularlistheader<int> y, z;

   // test size
   cout << "Initial size of y and z = "
        << y.size() << ", "
        << z.size() << endl;

   // test insert
   y.insert(0, 2);
   y.insert(1, 6);
   y.insert(0, 1);
   y.insert(2, 4);
   y.insert(3, 5);
   y.insert(2, 3);
   cout << "Inserted 6 integers, list y should be 1 2 3 4 5 6" << endl;
   cout << "Size of y = " << y.size() << endl;
//测试删除函数
y.erase(5);

//测试输出函数
   y.output(cout);
   cout << endl << "Testing overloaded <<" << endl;
   cout << y << endl;

   // test indexOf
   int index = y.indexOf(4);
   if (index < 0) cout << "4 not found" << endl;
   else cout << "The index of 4 is " << index << endl;

   index = y.indexOf(7);
   if (index < 0) cout << "7 not foundd" << endl;
   else cout << "The index of 7 is " << index << endl;

//测试迭代器
  yiterator<int> *gi= y.iteratord(y.first());

   gi->outputd();
   cout<<"aaaa";
   return 0;
}
  • 测试结果

Initial size of y and z = 0, 0

Inserted 6 integers, list y should be 1 2 3 4 5 6

Size of y = 6

 

1 2 3 4 5

 

Testing overloaded <<

 

1 2 3 4 5

Aaaa

 

The index of 4 is 37 not foundd1 2 3 4 5

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值