template <typename T> class LinearList { public: LinearList(); ~LinearList(); virtual int Size() const = 0; //返回线性表所能够存储的最大长度 virtual int Length() const = 0; //当前线性表的长度 virtual int Search(T &x) const = 0; virtual int Locate(int i) const = 0; virtual bool getData(int i,T &x) const = 0; virtual void setData(int i,T &x) = 0; virtual bool Insert(int i,T &x) = 0; virtual bool Remove(int i,T &x) = 0; virtual bool IsFull() const = 0; virtual bool IsEmpty() const = 0; virtual void input() = 0; virtual void output() const = 0; virtual void Sort() = 0; virtual LinearList<T> operator=(LinearList<T> &L) = 0; //支持线性表的复制 };
对于顺序表,其特点有如下公式:
Loc(i) = Loc(j) + (i-j) * sizeof(T)
类定义如下:
//注: 对于某些不知含义的C++关键词的含义以及用法, // 请参考系列博客:http://blog.csdn.net/column/details/zjf666.html const int defaultSize = 10; template <class T> class SeqList : public LinearList<T> { public: SeqList(int sz = defaultSize); SeqList(SeqList<T> &L); ~SeqList() { delete []data; } int Size() const { return maxSize; } int Length() const { return last + 1; } int Search(T &x) const; int Locate(int i) const; bool getData(int i,T &x) { if (i > 0 && i <= last+1) { x = data[i-1]; return true; } else { return false; } } void setData(int i,T &x) { if (i > 0 && i <= last+1) { data[i-1] = x; } } bool Insert(int i,T &x); bool Remove(int i,T &x); bool IsFull() const { return last == maxSize-1; } bool isEmpty() const { return last == -1; } void input(); void output(); void Sort(); SeqList<T> operator=(SeqList<T> &L); protected: T *data; //数组 int maxSize; //最大可容纳量 int last; //当前已存元素的最后一个位置 void reSize(int newSize); //改变data数组的空间大小 };
1) 构造函数与复制构造函数
template <typename T> SeqList<T>::SeqList(int sz) //构造顺序表 { if (sz > 0) { maxSize = sz; last = -1; //表的实际长度置空 data = new T[sz]; checkNew(data); //检查数组是否分配成功 } } template <typename T> SeqList<T>::SeqList(SeqList<T> &L) { maxSize = L.Size(); last = L.Length() -1; data = new T[maxSize]; checkNew(data); T value; for (int i = 1; i <= L.Length(); ++i) { L.getData(i,value); //将数据从原表中取出 data[i-1] = value; //将数据插入到新的表中 } }
2) 私有操作:扩充顺序表的的存储数组空间大小
template <typename T> void SeqList<T>::reSize(int newSize) { if (newSize <= 0) //无效的数组长度 { cerr << "invalid size!" << endl; exit(1); } if (newSize != maxSize) { T *newArr = new T[newSize]; //重新分配新的数组 checkNew(newArr); int times = last + 1; //获得原数组长度 T *srcPtr = data; T *destPtr = newArr; while (times --) //将原数组内容复制到新的数组 { *destPtr ++ = *srcPtr ++; } delete []data; //不要忘记释放原data内存! data = newArr; maxSize = newSize; } } //在应用调用具有SeqList类型返回值的函数时,都要使用复制构造函数,用以返回运算结果
3) 搜索和定位操作
template <typename T> int SeqList<T>::Search(T &x) const { for (int i = 0; i <= last ; ++i) { if (data[i] == x) { return i + 1; //表项序号恰比它在数组中的实际存放的位置序号少1 } } return 0; } template <typename T> int SeqList<T>::Locate(int i) const { if (i >= 1 && i <= last) return i; return 0; }
4) 顺序表的插入与删除操作
template <typename T> bool SeqList<T>::Insert(int i,T &x) { if (last + 1 == maxSize) //表满 return false; if (i < 0 || i > last + 1) //表项参数错误 return false; for (int index = last; index >= i; -- index) //依次后移,空出i号位置 { data[index] = data[index - 1]; } data[i] = x; ++ last; //表长+1[勿忘] return true; } template <typename T> bool SeqList<T>::Remove(int i,T &x) { if (last == -1) //表空 return false; if (i < 1 || i > last + 1) //表项参数错误 return false; x = data[i - 1]; for (int index = i; index <= last ; ++index) { data[index - 1] = data[index]; //循环前移,将i-1位置填充 } -- last; //修改表长 return true; }
5) 输入输出操作
template <class T> void SeqList<T>::input() { while (1) { cin >> last; //输入数组最后一个元素所在位置 if (last <= maxSize - 1) break; cout << "The value of last is error,please try again!" << endl; } for (int i = 0; i <= last; ++i) { cout << i + 1 << ": "; cin >> data[i]; } } template <class T> void SeqList<T>::output() const { for (int i = 0; i <= last; ++i) { cout << "#" << i + 1 << ": " << data[i] << endl; } }
6) 赋值操作
template <class T> SeqList<T> &SeqList<T>::operator=(const SeqList<T> &L) { if (maxSize < L.Length()) { reSize(L.Length() * 2); } maxSize = L.Length() * 2; last = L.Length() - 1; T value; for (int i = 1;i <= last + 1; ++i) { L.getData(i,value); data[i - 1] = value; } return * this; }
顺序表的所有操作的实现中,最复杂、最耗时的就是搜索、插入和删除运算的实现。搜索的时间代价主要看重搜索所采用的方法,是采用顺序搜索,还是二叉搜索等,而顺序表的插入和删除的时间代价主要是看循环内的数据移动次数。
C++数据结构与算法_1_线性表 --顺序表的实现与分析,布布扣,bubuko.com
原文地址:http://blog.csdn.net/zjf280441589/article/details/37870159