我们利用静态分配的数组来实现的顺序表的局限还是挺大的,主要在于它的容量是预先定好的,用户不能根据自己的需要来改变。如果为了后续用户能够自己调整顺序表的大小,动态地分配数组空间还是很有必要的。基于动态分配的数组的顺序表绝大部分跟基于静态分配的数组的顺序表是一样的,只需在后者程序上改动一小部分即可。

  第一,我们不需定义一个容量常量CAPACITY,而是定义一个私有变量myCapacity。

  第二,类的构造函数需要改进一下。我们需要类在被实例化时自动申请内存,即需添加下边程序:

ElementType * seqList = new ElementType(myCapacity);
assert(seqList != NULL);

  第三,类的析构函数需要添加下边一句:

delete [] seqList;

  上面三点说的还有所欠缺。Larry Nyhoff在《数据结构与算法分析》第253页中提到设计类时要记住的一条规则:

  如果类在运行时使用new分配内存,则它应该提供:

  • 把动态分配的内存还给堆的析构函数
  • 编译器用来创建不同副本的复制构造函数
  • 程序员用来创建不同副本的赋值运算符

  基于动态分配的数组的顺序表设计的类如下:

 1 // seqlist.h
 2 #ifndef SEQLIST
 3 #define SEQLIST
 4 
 5 #include <iostream>
 6 #include <cassert>
 7 #include <algorithm>
 8 
 9 using namespace std;
10 
11 typedef int ElementType;
12 
13 class SeqList
14 {
15 public:
16     SeqList(const int maxsize = 1024);
17     virtual ~SeqList();
18     SeqList(const SeqList& origList);                   // 拷贝构造函数,记得防止浅拷贝
19     const SeqList& operator=(const SeqList& rightHandSide);      // 重载赋值运算符,记得防止浅拷贝
20     bool empty() const;
21     void clear();
22     bool insert(const int pos, const ElementType val);
23     bool erase(const int pos);
24     void display() const;
25     bool setSeqList(const ElementType *tmpList, const int len);
26     int getLenOfList() const;
27     ElementType getItem(const int pos);
28     ElementType * getSeqList();                      // 保留,不推荐使用,因为在使用过程中无法进行越界检查
29 
30 private:
31     int myCapacity;                             // 自定义顺序表容量
32     int lenOfList;                              // 顺序表长度
33     ElementType * seqList;
34 
35 };
36 
37 #endif

  实现程序为:

  1 // seqlist.cpp
  2 #include <iostream>
  3 #include <cassert>
  4 #include "seqlist.h"
  5 
  6 using namespace std;
  7 
  8 SeqList::SeqList(const int maxsize)
  9 {
 10     // initialization
 11     lenOfList = 0;
 12     myCapacity = maxsize;
 13     seqList = new ElementType[myCapacity];
 14     // assert(seqList != NULL);
 15     if (seqList == NULL)
 16     {
 17         cerr << "Inadequate memory to allocate stack." << endl;
 18         throw bad_alloc();
 19     }
 20 }
 21 
 22 SeqList::~SeqList()
 23 {
 24     delete[] seqList;
 25 }
 26 
 27 SeqList::SeqList(const SeqList& origList)
 28 {
 29     myCapacity = origList.myCapacity;
 30     lenOfList = origList.lenOfList;
 31     seqList = new ElementType[myCapacity];
 32     // assert(seqList != NULL);
 33     if (seqList == NULL)
 34     {
 35         cerr << "Inadequate memory to allocate stack." << endl;
 36         throw bad_alloc();
 37     }
 38     else
 39     {
 40         for (int i = 0; i < lenOfList; i++)
 41         {
 42             seqList[i] = origList.seqList[i];
 43         }
 44     }
 45 }
 46 
 47 const SeqList& SeqList::operator=(const SeqList& rightHandSide)
 48 {
 49     // 确保不是自我赋值
 50     if (this != &rightHandSide)
 51     {
 52         // 如果需要,分配一个新数组
 53         if (myCapacity != rightHandSide.myCapacity)
 54         {
 55             delete[] seqList;
 56             myCapacity = rightHandSide.myCapacity;
 57             seqList = new ElementType[myCapacity];
 58             // assert(seqList != NULL);
 59             if (seqList == NULL)
 60             { 
 61                 cerr << "Inadequate memory to allocate stack." << endl;
 62                 throw bad_alloc();
 63             }
 64         }
 65 
 66         lenOfList = rightHandSide.lenOfList;
 67         for (int i = 0; i < lenOfList; i++)
 68         {
 69             seqList[i] = rightHandSide.seqList[i];
 70         }
 71     }
 72     return *this;
 73 }
 74 
 75 bool SeqList::empty() const
 76 {
 77     return lenOfList == 0;
 78 }
 79 
 80 void SeqList::clear()
 81 {
 82     lenOfList = 0;
 83     fill(seqList, seqList + myCapacity - 1, 0);
 84 }
 85 
 86 bool SeqList::insert(const int pos, const ElementType val)
 87 {
 88     bool success = false;
 89     // assert(lenOfList != CAPACITY);    // 这里的assert分成两行写,是为了方便定位错误发生的地方
 90     // assert(0 <= pos <= lenOfList);
 91     if (lenOfList == myCapacity)
 92     {
 93         cerr << "No space for insertion!" << endl;
 94     }
 95     else if (pos < 0 || pos > lenOfList)
 96     {
 97         cerr << "The position " << pos << 
 98             " you want to insert is less than zero or exceeds the length of the list!" << endl;
 99         throw out_of_range("throw out_of_range");    // 抛出一个越界异常
100     }
101     else
102     {
103         int tmpCount = lenOfList - pos;
104         for (int i = 0; i < tmpCount; i++)
105         {
106             seqList[lenOfList - i] = seqList[lenOfList - i - 1];
107         }
108         seqList[pos] = val;
109         lenOfList++;
110         success = true;
111     }
112     return success;
113 }
114 
115 bool SeqList::erase(const int pos)
116 {
117     bool success = false;
118     // assert(lenOfList != 0);
119     // assert(0 <= pos <= lenOfList);
120     if (lenOfList == 0)
121     {
122         cerr << "There is no elements in the list!" << endl;
123     }
124     else if (pos < 0 || pos > lenOfList)
125     {
126         cerr << "The position " << pos << 
127             " you want to erase is less than zero or exceeds the length of the list!" << endl;
128         throw out_of_range("throw out_of_range");    // 抛出一个越界异常
129     }
130     else
131     {
132         int tmp = lenOfList - pos;
133         for (int i = 0; i < tmp - 1; i++)
134         {
135             seqList[pos + i] = seqList[pos + i + 1];
136         }
137         seqList[lenOfList - 1] = 0;
138         lenOfList--;
139         success = true;
140     }
141     return success;
142 }
143 
144 void SeqList::display() const
145 {
146     cout << "***Start Displaying***" << endl;
147     if (lenOfList == 0)
148     {
149         cerr << "There is no element in the the list!" << endl;
150     }
151     else
152     {
153         for (int i = 0; i < lenOfList; i++)
154         {
155             cout << i << " : " << seqList[i] << endl;
156         }
157         cout << "***End Displaying***" << endl;
158     }
159 }
160 
161 bool SeqList::setSeqList(const ElementType *tmpList, const int len)
162 {
163     // assert(len <= CAPACITY);
164     bool success = false;
165     if (len <= myCapacity)
166     {
167         for (int i = 0; i < len; i++)
168         {
169             seqList[i] = *(tmpList++);
170         }
171         lenOfList = len;
172         success = true;
173     }
174     else
175     {
176         cerr << "The length of the array you set exceeds the CAPACITY." << endl;
177         throw out_of_range("throw out_of_range");    // 抛出一个越界异常
178     }
179     return success;
180 }
181 
182 int SeqList::getLenOfList() const
183 {
184     return lenOfList;
185 }
186 
187 ElementType SeqList::getItem(const int pos)
188 {
189     // assert(0 <= pos <= lenOfList);
190     if (pos < 0 || pos > lenOfList)
191     {
192         cerr << "The item at " << pos << " you want to get does not exist!" << endl;
193         throw out_of_range("throw out_of_range");    // 抛出一个越界异常
194     }
195     else
196     {
197         return seqList[pos];
198     }
199 }
200 
201 ElementType * SeqList::getSeqList()
202 {
203     return seqList;
204 }
seqlist.cpp

相关文章:

  • 2021-05-06
  • 2021-06-14
  • 2021-04-18
  • 2021-06-20
  • 2022-12-23
  • 2021-05-03
  • 2021-10-15
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-12-04
  • 2021-04-22
  • 2021-12-30
相关资源
相似解决方案