zoukankan      html  css  js  c++  java
  • 顺序存储线性表的分析

    1. SeqList类的效率分析

    长度相同的两个SeqList,插入和删除操作的平均耗时不一定相同

    如SeqList<int> s1和SeqList<string> s2的插入操作,由于string的赋值涉及到字符串的拷贝,这就比int类型的拷贝耗时,因此s1和s2的平均耗时是不同的。

    2、问题一:对象赋值的问题

     1 StaticList<int* ,5> s1;
     2 StaticList<int* ,5> s2;
     3 for(int i=0 ;i<s1.capacity();i++)
     4 {
     5     s1.insert(0, new int(i));//s1线性表中第0个位置插入堆空间中的一个地址,地址中存的是i
     6 }                        //s1中有5个指针每个指针指向一个堆空间中的一个的整形数据
     7 
     8     s2=s1;//赋值可以成功 但是两个对象中的m_space[i]都指向同一个int*类型的堆空间
     9 
    10 for(int i=0 ;i<s1.capacity();i++)
    11 {
    12     delete s1[i];//即释放所指向所指向的堆空间
    13     delete s2[i];   
    14 }

    delete s1;
    delete s2;

    同一个堆空间被释放了两次,第二次释放了未定义的堆空间,一定发生问题,置于何时会变成bug就不知道了

    问题二:对象拷贝问题

    解决方案:对于容器类型的类,可以考虑禁用拷贝构造和赋值操作。将拷贝构造函数和赋值的的操作符声明为protected(可以被子类访问不能被外界访问的)

    List.h和SeqList.h的改进

    //List.h

     1 #ifndef _LIST_H_
     2 #define _LIST_H_
     3 
     4 #include "Object.h"
     5 
     6 namespace DTLib {
     7 
     8 template <typename T>
     9 class List : public Object
    10 {
    11 protected:
    12     //禁用拷贝构造函数和赋值操作符   即将拷贝构造函数和赋值操作法声明为保护的;
    13     List(const List&);
    14     List& operator=(const List&);
    15 public:
    16     //由于以上手动添加了拷贝构造函数,编译将不再提供
    17     //默认的一些构造函数。这里需要手工加上无参构造函数
    18     List(){}
    19     virtual bool insert(const T& e) = 0;//往线性表尾部插入元素
    20     virtual bool insert(int index, const T& elem) = 0;
    21     virtual bool remove(int index) = 0;
    22     virtual bool get(int index, T& elem) const = 0;
    23     virtual int length() const = 0;
    24     virtual void clear() = 0;
    25 };
    26 
    27 }
    28 
    29 #endif // _LIST_H_

    //SeqList.h

      1 #ifndef _SEQLIST_H_
      2 #define _SEQLIST_H_
      3 
      4 #include "list.h"
      5 #include "Exception.h"
      6 
      7 namespace DTLib {
      8 
      9 template <typename T>
     10 class SeqList : public List<T>
     11 {
     12 protected:
     13     T* m_array;    //顺序存储空间
     14     int m_length;  //当前线性表长度
     15 public:
     16     //插入元素
     17     bool insert(int index, const T &elem)  //O(n)
     18     {
     19         bool ret = ((0 <= index)&&(index <= m_length));
     20         ret = ret && (m_length < capacity());
     21 
     22         if(ret){
     23             //将index及其之后的元素向后移动一个位置
     24             for(int pos=m_length-1; pos>=index; pos--){
     25                 m_array[pos + 1] = m_array[pos];
     26             }
     27             //新元素插入在index位置
     28             m_array[index] = elem;
     29             m_length++;
     30         }
     31 
     32         return ret;
     33     }
     34 
     35     bool insert(const T& e) //O(n)  ==>往线性表尾部插入元素
     36     {
     37         return insert(m_length, e);
     38     }
     39 
     40     //删除元素
     41     bool remove(int index)     //O(n)
     42     {
     43         bool ret = ((0 <= index)&&(index < m_length));
     44 
     45         if(ret){
     46             for(int pos=index; pos<m_length-1; pos++){
     47                 m_array[pos] = m_array[pos + 1];
     48             }
     49 
     50             m_length--;
     51         }
     52 
     53         return ret;
     54     }
     55 
     56     //设置元素
     57     bool set(int index, const T& elem)  //O(1)
     58     {
     59         bool ret = ((0 <= index)&&(index < m_length));
     60 
     61         if(ret){
     62             m_array[index] = elem;
     63         }
     64 
     65         return ret;
     66     }
     67 
     68     //获取元素
     69     bool get(int index, T &elem) const  //O(1)
     70     {
     71         bool ret = ((0 <= index)&&(index < m_length));
     72 
     73         if(ret){
     74            elem =  m_array[index];
     75         }
     76 
     77         return ret;
     78     }
     79 
     80     //当前长度
     81     int length()const    //O(1)
     82     {
     83         return m_length;
     84     }
     85 
     86     //清空线性表
     87     void clear()        //O(1)
     88     {
     89         m_length = 0;
     90     }
     91 
     92     //顺序存储线性表的数组访问方式
     93     T& operator[](int index)  //O(1)
     94     {
     95         if((0<=index) && (index<m_length)){
     96             return m_array[index];
     97         }else{
     98             THROW_EXCEPTION(IndexOutOfBoundsException, "Parameter index is invalid ...");
     99         }
    100     }
    101 
    102     T operator [](int index) const  //O(1)
    103     {
    104         return (const_cast<SeqList<T>&>(*this))[index];
    105     }
    106 
    107     //顺序存储空间的容量
    108     virtual int capacity()const = 0;
    109 };
    110 
    111 }
    112 
    113 #endif // _SEQLIST_H_
  • 相关阅读:
    Linux学习 -- Shell编程 -- 字符截取命令
    Linux学习 -- Shell编程 -- 正则表达式
    Linux学习 -- Shell基础 -- Bash变量
    Linux学习 -- Shell基础 -- Bash基本功能
    Linux学习 -- Shell基础 -- 概述
    Linux学习 -- 备份与恢复
    Linux学习 -- 启动管理
    Linux学习 -- 日志管理
    chapter9_3 协同程序实现迭代器
    chapter9_2 管道与过滤器
  • 原文地址:https://www.cnblogs.com/zhaobinyouth/p/9588315.html
Copyright © 2011-2022 走看看