链表测试

List.h

#ifndef LIST_H
#define LIST_H

#include"Object.h"
namespace DTLib {
template<typename T>
class List :public Object
{
protected:
    //这里是为了干什么的()
    List(const List&);
    List& operator= (const List&);
public:
    List(){}
    virtual bool insert(const T& e)=0;
    virtual bool insert(int i,const T& e)=0;
    virtual bool remove(int i)=0;
    virtual bool set(int i,const T& e)=0;
    virtual bool get(int i,T& e)const=0;
    virtual int length()const =0;
    virtual void clear()=0;
};
}



#endif // LIST_H

这里将拷贝构造函数 和赋值函数 写在了protected内;

是为了避免 其带来的错误,具体的可以看数据结构 -210-212

SeqList.h

#ifndef SEQLIST
#define SEQLIST
#include "Object.h"
#include "List.h"
#include "Exception.h"

namespace DTLib {
template<typename T>
class SeqList :public List<T>
{
protected:
    T* m_array;  //数组指针
    int m_length;
public:
     virtual bool insert(const T& e){
        return insert(m_length,e);
    }
     bool insert(int i,const T& e){
         bool ret = ((i>=0)&&(i<=m_length));
         ret =ret&&(m_length<capacity());
         if(ret){
             //插入位置往后的所有元素的移动  是否耗时 取决于插入的类型
             for(int p=m_length-1;p>=i;p--){
                 m_array[p+1]=m_array[p];
             }
            m_array[i]=e;
         }
         m_length++;
         return ret;
     }

     bool remove(int i){

          bool ret = ((i>=0)&&(i<m_length));
          if(ret){
              //插入位置往后的所有元素的移动
              for(int p=i;p<=m_length-1;p++){
                  m_array[p]=m_array[p+1];
              }
          }
          m_length--;
          return ret;

     }
     
     bool set(int i,const T& e){
         bool ret = ((i>=0)&&(i<m_length));
         if(ret){
                m_array[i] = e;
             }
         return ret;
     }
     
     bool get(int i,T& e){
         bool ret = ((i>=0)&&(i<m_length));
         if(ret){
                e = m_array[i] ;
             }
         return ret;
     }
     
     int length()const {
         return m_length;
     }

     void clear(){
         m_length= 0;
     }

     T& operator[](int i){
          bool ret = ((i>=0)&&(i<m_length));
          if(ret){
                 return m_array[i];
              }
          else{
              THROW_EXCEPTION(InvalidOperationException,"Parameter i is invalid....");
          }
     }

     T operator[](int i) const{
         //去除const 属性
        return const_cast<SeqList<T>&> (*this)[i];
     }

     virtual int capacity() const=0;
};

}


#endif // SEQLIST

DynamicList.h

#ifndef DYNAMOCLIST_H
#define DYNAMOCLIST_H

#include"SeqList.h"
#include"Exception.h"
//动态申请 连续堆空间 作为顺序存储空间  怎么保证异常的安全性(是什么?基本保证是什么)
namespace DTLib {
template<typename T>
class DynamicList : public SeqList<T>
{
protected:
    int m_capacity;
public:
    //构造函数 直接初始化
    DynamicList(int capacity){
       this->m_array = new T[capacity];
        if(this->m_array!=NULL){
            this->m_length=0;
            this->m_capacity=capacity;
        }
        else{
            THROW_EXCEPTION(NoEnoughMemoryException," no enough memory for object...");
        }
    }
    int capacity()const{

        return m_capacity;
    }

    //重新设置存储空间的大小
    void resize(int capacity)
    {

        if(capacity!=m_capacity)
        {
            T* array = new T[capacity];  //考虑一下这里为什么不直接用m_array =.. 呢?
            if(array != NULL )
            {
                //保持原来的顺序 or 或则保持原来所有的数组
               int length =(this->m_length < capacity ? this->m_length : capacity);
               for(int i =0;i<length;i++)
            {
                array[i]= this->m_array[i];
            }

            //这个指针 体现了什么 ,如果我不用这个指针 直接delete  有什么问题??
            // 这里注释这条语句,直接在最后面 delete[] this->m_array 有什么问题

            T* temp =this->m_array; //这个其实就是 先保存原理啊的地址,为了 后面删除原来的地址空间内存

            this->m_array =array;
            this->m_length = length;
            this->m_capacity = capacity;
            //delete[] this->m_array;   //自己想想为什么

            delete[] temp;//这里的异常安全 是 当T 是类对象,delete 会触发类对象的析构函数 如果析构函数中 存在异常返回,那么下面的语句就没啥用了

            }
            else
            {
              THROW_EXCEPTION(NoEnoughMemoryException," resize __ no enough memory for object...");
            }
        }
    }
//归还空间
    ~DynamicList(){
        delete [] this->m_array; //这里是调用自己的delete[]来删除数组
}

};

}

#endif // DYNAMOCLIST_H

链表:

#ifndef LINKLIST_H
#define LINKLIST_H

#include "List.h"
#include "Exception.h"

namespace DTLib {
template<typename T>
class LinkList :public List<T>
{
protected:
    struct Node:public Object{
        //头节点的隐患
        T value;//这里创建了T 的对象 如果这个对象(一般是类)中 有异常 会直接导致程序无法继续执行下去;
        Node* next;
    };
    //mutable Node m_header; //为什么用这个mutable  const 中 不可以改变值 加上mutable 就可以;
    //这里为什么这样去使用    使用匿名的类型  不能调用构造函数
    //这里一定要通多继承 来同化m_header, 否则测函数接口的时候 不会成功
    mutable struct:public Object{
        char reseved[sizeof(T)];
        Node* next;
    }m_header;

    int m_length;
    //reinterpret_cast 这里要进行强制类型的转换
    Node* position(int i)const{
        Node* ret =reinterpret_cast<Node*>(&m_header);
        for(int t=0;t<i;t++){
            ret=ret->next;
        }
        return ret;
    }
public:
    //构造函数 初始化成员
    LinkList(){
        m_header.next = NULL;
        m_length = 0;
    }
     bool insert(const T& e){
        return insert(m_length,e);
    }

     bool insert(int i,const T& e){
         bool ret = ((i>=0)&&(i<=m_length));
         if(ret){
             Node* node = new Node();
             if(node!=NULL){
                 Node* current = position(i);
                 /*
                 Node* current = &m_header;
                 for(int t=0;t<i;t++){
                     current=current->next;
                 }*/
                 //插入的关键
                 node->value = e;
                 node->next =current->next;
                 current->next =node;
                 m_length++;

             }else {
                 THROW_EXCEPTION(NoEnoughMemoryException,"no node enough memory to insert");
             }
         }

         return ret;
    }
     bool remove(int i){
          bool ret = ((i>=0)&&(i<m_length));
          if(ret){
               Node* current = position(i);
               //删除的关键
               Node* toDel = current->next;
               current->next=toDel->next;
               delete toDel;
                m_length--;
          }

          return ret;

    }

     bool set(int i,const T& e){
         bool ret = ((i>=0)&&(i<m_length));
         if(ret){
             Node* current = position(i);
             current->next->value = e;
         }
         return ret;

    }
     //Get 的重载 
     T get(int i){
         T ret;
         if(get(i,ret)){
             return ret;
         }else{
             THROW_EXCEPTION(IndexOutOfBoundsException,"Invalid  i in get()");
         }
 }
     bool get(int i,T& e)const{
         bool ret = ((i>=0)&&(i<m_length));
         if(ret){
           Node* current = position(i);
           e = current->next->value;

         }
         return ret;
    }

     int length()const{
        return m_length;
    }
//遍历节点 删除所有的
     void clear(){
      while(m_header.next!=NULL){
          Node* toDel =m_header.next;
          m_header.next=toDel->next;
          delete toDel;
      }
      m_length=0;
    }
     ~LinkList(){
     clear();
 }
};

}

#endif // LINKLIST_H

测试:


#include <iostream>
#include"exception.h"
#include "Object.h"
#include"SmartPointer.h"
#include"List.h"
#include "SeqList.h"
#include "StaticList.h"
#include"DynamicList.h"
#include "staticarray.h"
#include "dynamicarray.h"
#include "LinkList.h"

using namespace std;
using namespace DTLib;


class Test{
public:
    Test()
    {
        throw(0);
    }
};

int main()
{

    LinkList<int> list;

    for(int i=0;i<5;i++){
        list.insert(i);

    }

    for(int i=0;i<list.length();i++){
        cout<<list.get(i)<<endl;
    }

    //LinkList<Test> list;
    //cout<<"xly"<<endl;

    return 0;
}

其中Test 测试 告诉我:更改代码后 一定要再重新测试代码的正确性!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值