线性表的顺序结构实现
代码实现
- 抽象基类AbstractList.h文件
template<class T>
class AbstractList
{
public:
virtual bool isEmpty() const=0;
virtual int length() const=0;
virtual bool findElement(int k,T& x)const =0;
//find the element whose index is k and assign the result to the x
virtual int searchElement(const T& x)const =0;
//search the x element and return its index
virtual AbstractList<T>& delete(int k,T& x)=0;
//delete the x element ,return the deleted Linklist and return the deleted element
virtual AbstractList<T>& insert(int k,const T& x)=0;
//insert the element at the position whose index is k
virtual void output() const=0;
};
分析与总结
-
使用“virtual … =0”的方式去声明纯虚函数,而在结尾加上对应的const,则表明该成员函数并不能够对类的成员进行修改
-
对于大型的数据量,要尽量调用的引用来进行传值,减少内存消耗
-
如果不需要修改形参的值,可在形参前面加上const,声明为的常量
-
LinerList.h文件
#ifndef _LINERLIST_H
#define _LINERLIST_H
#include "AbstractList.h"
#include <iostream>
using namespace std;
template <class T>
class LinerList:public AbstractList<T>
{
public:
LinerList(int maxSize=10);
~LinerList(){
delete []element;}
bool isEmpty()const{
return length==0;};
int getLength()const {
return length;};
bool findElement(int k,T& x)const;
//find the element whose index is k and assign the result to the x
int searchElement(const T& x)const;
//search the x element and return its index
AbstractList<T>& Delete(int k,T& x);
//delete the x element ,return the deleted Linklist and return the deleted element
AbstractList<T>& insert(int k,const T& x);
//insert the element at the position whose index is k
void output() const;
AbstractList<T>& add(const T& x);
private:
int length;
int maxSize;
T* element;
};
template <class T>
LinerList<T>::LinerList(int maxSize)
{
element = new T[maxSize];
this->maxSize = maxSize;
length = 0;
}
//find the element whose index is k and assign the result to the x
template <class T>
bool LinerList<T>::findElement(int k,T& x)const
{
if(k<0 || k>length)
{
cout<<"error:out of index!"<<endl;
return false;
//the result of the function is the type of bool
}
//the index of array is from zero!
x = element[k-1];
return true;
//the reference cannot be changed!
//the meaning of the = is copy not change the reference!
}
//search the x element and return its index
template<class T>
int LinerList<T>::searchElement(const T& x)const
{
if(isEmpty()) return -1;
//for the illegal value use illegal value to represent for!
for(int i = 0;i < length;i++)
{
if(element[i] == x)
{
return ++i;
//caution:the index of the LinerList is one more than array!
}
}
return -1;
}
//delete the x element ,return the deleted Linklist and return the deleted element
template<class T>
AbstractList<T>& LinerList<T>::Delete(int k,T& x)
{
if(findElement(k,x))
{
for(int i = k; i < length; i ++) {
element[i-1] = element[i];
}
length --;
return *this;
}
else
{
cout<<"out of the index"<<endl;
return *this;
}
//almost forget it
}
//insert the element at the position whose index is k
template<class T>
AbstractList<T>& LinerList<T>::insert(int k,const T& x)
{
if(!(length == 0 && k == 1))
{
if(k>length || k<1) {
cout<<"out of the index!"<<endl;
return *this;
}
int i = 0;
//move and copy the revelant element
for(i = length - 1; i >= k-1 && i >= 0; i --) {
element[i + 1] = element[i];
}
//insert the element in the targeted position
}
element[k - 1] = x;
length ++;
return *this;
}
template <class T>
void LinerList<T>::output() const
{
cout<<"the length of the LinerList is:"<<length<<endl;
cout<<"List is:";
for(int i = 0;i < length;i ++)
{
cout<<element[i]<<" ";
}
cout<<endl;
}
template <class T>
AbstractList<T>& LinerList<T>::add(const T& x)
{
if(length == maxSize)
{
cout<<"out of memeory!add the element absortively"<<endl;
return *this;
}
element[length] = x;
length ++;
return *this;
}
#endif // _LINERLIST_H
- main测试文件
#include <iostream>
#include "LinerList.h"
using namespace std;
int main()
{
LinerList<int> L(5);
cout<<"length:"<<L.getLength()<<endl;
cout<<"is empty:"<<L.isEmpty()<<endl;
L.add(1).add(2).add(3).add(4);
L.output();
L.insert(1,8).insert(1,88);
L.output();
int z;
L.findElement(1,z);
cout<<"the found element is:"<<z<<endl;
L.Delete(3,z);
cout<<"the deleted element is : "<<z<<endl;
return 0;
}
分析与总结
- 引用是没有办法被修改的,而对引用使用赋值符号,并不是将修改引用的指向,是将等号的左边的对象的属性,完全复制到等号的右边的对象的属性。注意对等号的理解
- 注意下标:对于使用者而言,下标是从1开始的,但是对于程序而言,下标是从0开始的!彼此转换,记得加一减一。用户输入的索引是从1开始的,程序员是从零开始,注意两者之间的转换
- 学会使用异常处理机制,来替代单纯的输入输出语句
- 编写程序的过程注意分步处理,按照情况进行分类
遇到的异常
cannot declare variable ‘…’ to be of abstract type ‘…’
- 没有彻底实现所有的虚函数——漏了const的常量的声明
- 只需要加上对应的const常量声明即可
- 只需要加上对应的const常量声明即可
udefined reference to ‘…’
- 对于模板类而言,C++中部分编译器,不支持声明.h和实现.cpp分开写——只需要将之整合到一个文件中即可