您的位置:首页 > 理论基础 > 数据结构算法

数据结构之顺序表

2015-06-29 18:08 218 查看
顺序表是最简单的一种数据结构,数组就是一个简单的顺序表,大家可以利用对数组的认识来理解顺序表。顺序表的最大特点就是存储在一片连续的地址空间。这一特点决定了顺序表的优点和不足:
优点:由于地址连续,所以可利用一个首地址作为整个顺序表的标识。同时,地址连续的顺序表可以实现随机存储,也就是说可以利用下标访问元素,这一点最大的好处是可以节省访问时间,提高程序运行效率。
不足:为保证地址空间的连续性,顺序表每删除一个元素都要移动后面所有元素,这会造成很多不必要的操作。
由于顺序表实现简单,所以平时用的还是比较多的。以后各种复杂数据结构都是基于顺序表改进得到的。
顺序表源代码:

</pre><p align="left"><pre name="code" class="cpp">#ifndef _SEQLIST_H
#define _SEQLIST_H

#include <iostream>

const int defaultSize=10;

template<typename dataType>
class seqList;//声明模板类

template<typename dataType>
std::ostream& operator<<(std::ostream&,const seqList<dataType>&);//声明模板函数

template<typename dataType>
class seqList
{
public:
seqList(const int size=defaultSize):maxSize(size),length(0)//(默认)构造函数
{
elements=new dataType[maxSize];
}
seqList(const seqList& other)//复制构造函数
{
this->maxSize=other.maxSize;
this->length=other.length;
this->elements=new dataType[maxSize];
for(int i=0;i<this->length;++i)
this->elements[i]=other.elements[i];
}
seqList& operator=(const seqList& other)//赋值操作符
{
if(this->elements==other.elements)
return *this;//自我赋值,返回自身
delete[] this->elements;
this->maxSize=other.maxSize;
this->length=other.length;
this->elements=new dataType[this->maxSize];
for(int i=0;i<this->length;++i)
this->elements[i]=other.elements[i];
}
~seqList(){delete[] elements;}//析构函数

bool insertElement(const dataType&);//向表尾插入元素
bool deleteElement(const int&);//删除指定位置元素
dataType getElement(const int&) const;//返回指定位置的元素
bool changeElemet(const int&,const dataType&);//修改指定位置元素
template<typename dataType>
friend std::ostream& //重载输出操作符
operator<< <dataType>(std::ostream&,const seqList<dataType>&);

private:
dataType* elements;//存放表元素
int maxSize;//表的最大容量
int length;//表的有效长度

};

template<typename dataType>  //向表尾插入元素
bool seqList<dataType>::insertElement(const dataType& elmt)
{
if(length>maxSize)
{
cerr<<"The seqList is full!"<<endl;
return false;
}
this->elements[length++]=elmt;
return true;
}
template<typename dataType>  //删除指定位置元素
bool seqList<dataType>::deleteElement(const int& index)
{
if(index>=maxSize||index>=length||index<0)
{
cerr<<"The subscrip is illegal!"<<endl;
return false;
}
for(int i=index;i<length;++i)
{
this->elements[i]=this->elements[i+1];
}
--length;
return true;
}
template<typename dataType>  //返回指定位置的元素
dataType seqList<dataType>::getElement(const int& index) const
{
if(index>=maxSize||index>=length||index<0)
{
cerr<<"The subscrip is illegal!"<<endl;
}
return this->elements[index];
}
template<typename dataType>  //修改指定位置元素
bool seqList<dataType>::changeElemet(const int& index,const dataType& elmt)
{
if(index>=maxSize||index>=length||index<0)
{
cerr<<"The subscrip is illegal!"<<endl;
return false;
}
this->elements[index]=elmt;
}
template<typename dataType> //重载输出操作符
std::ostream& operator<<(std::ostream& os,const seqList<dataType>& sqLst)
{
for(int i=0;i<sqLst.length;++i)
os<<sqLst.elements[i]<<" ";
os<<std::endl;
return os;
}

#endif


实现过程中要注意的两点:
一是重载赋值操作符(=)时为防止自身赋值出问题所做的判断,针对不同的类的,这种判断不能一概而论,有的可以直接利用某个元素的相等来判断(如本例)。而有的类则需要判断类中很多个元素,甚至要考虑为此重载相等操作符。这里最常犯的错误是没有判断或者直接利用”==”判断了却没有重载”==”。前者会造成自我赋值时的错误,而后者主要是在手写代码时要注意。
二是对输出操作符(<<)的重载。这里问题比较多,要多说几句。
首先是输出操作符一般重载为友元函数,且其形式是较为固定的,这一点不明白的可以参考相关资料。
其次是关于模板类的友元关系声明,C++支持三种模板类的声明:
1. 普通函数的友元声明
即将友元关系授予一个特定的非模板函数,这个情况最简单,可以直接声明
template<typenameT>
class A
{
friend void fun(int&);//fun函数是非模板函数
};


2. 一般模板函数的友元声明
这种情况下,函数本身也是一个模板函数,函数所用的模板和类的模板“没有关系”,即两个模板是不同的
template<typenameT1>
class B
{
template<typename T2>
friend void fun(T2&);//fun是T2模板函数这和类的模板T1不同
};


这种情况下要注意友元声明前的template<typename T2>是必须要有的

3. 特定模板的友元声明
这种情况最为复杂,其要求将友元关系授予某些特定的模板函数,其中最常用的是和类模板相同的函数
template<typename T>
void fun(T&);//必须再前面声明
template<typename T>
class C
{
friendvoid fun<T>(T&);//fun函数所用模板和类相同
};


这里要注意fun后面的<T>是要写的(不写不会再编译时出错,但会在使用该函数时出问题),而且函数必须再类前做出声明
更为复杂的情况是模板函数有以类的模板为参数
template<typename T>
class C;//先声明类
template<typename T>
voidfun(T&,C<T>&);//必须再前面声明
template<typename T>
class C
{
friendvoid fun<T>(T&,C<T>);//fun函数所用模板和类相同
};


这里要想声明类,然后用类声明又有函数,再在类里面声明友元关系。本例中重载输出操作符及是这种情况。

最后要说明的是这些情况仅限于友元声明是的不同,友元函数实现是和正常情况下一样的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: