C++语言实现顺序表
C++语言实现顺序表
顺序表的定义及其特点
顺序表的定义是:把线性表中的所有表项按照其逻辑顺序依次存储到从计算机存储中指定存储位置开始的一块连续的存储空间中。 这样,线性表中第一个表项的存储位置就是被指定的存储位置,第i个表项(2≤\leq≤ i ≤\leq≤n)的存储位置紧接在第i一1个表项的存储位置的后面。假设顺序表中每个表项的数据类型为T,则每个表项所占用存储空间的大小(即字节数)大小相同,均为 sizeof(T),整个顺序表所占用存储空间的大小为n×\times× sizeof(T),其中n表示线性表的长度。
顺序表的特点是:
(1)在顺序表中,各个表项的逻辑顺序与其存放的物理顺序一致,即第i个表项存储于
第i个物理位置(1≤\leq≤ i ≤\leq≤n).
(2)对顺序表中所有表项,既可以进行顺序访问,也可以进行随机访问。 也就是说,既可以从表的第一个表项开始逐个访问表项,也可以按照表项的序号(亦称为下标)直接访问表项。
顺序表类定义及其主要操作
顺序表的类声明
class SeqList
{
private:
T *data;//存放数据的动态数组
int maxSize;//最大可容纳表项的项数
int last; //当前已存表项的最后位置(从0开始)
void reSize(int newSize); //改变数组空间大小
public:
SeqList(int sz); //构造函数
SeqList(SeqList<T>& L); //复制构造函数
~SeqList() {delete[ ] data;} //析构函数
int Size(){//求表最大容量
return maxSize;
}
int Length() {//计算表长度
return last+1;
}
int Search(T x);//搜索x在表中位置,函数返回表项序号
int Locate(int i);//定位第i个表项,函数返回表项序号
bool Insert(int i, T& x);//插入x在第i个表项之后
bool Remove(int i, T& x);//删除第i个表项之后,通过x返回表项的值
bool GetData(int i,T& x);//取第i个表项的值,以x引用返回
bool SetData(int i,T& x);//用x修改第i个表项的值
bool IsEmpty(){//判断表是否空否,是返回true,否返回false
return (last==-1) ? true : false;
}
bool IsFull(){//判读表是否满否,是返回true,否返回false
return (last = maxSize - 1) ? true : false;
}
void input();//输入数据
void output();//打印数据
};
构造函数和复制构造函数
template <class T>
inline SeqList<T>::SeqList(int sz)
{
if (sz > 0) {
maxSize = sz; last = -1;
data = new T[maxSize]; //创建表存储数组
if (data == NULL) //动态分配失败
{
cout<<"储存分配错误!"<<endl;
}
}
}
template <class T>
inline SeqList<T>::SeqList(SeqList<T>& L)
{
//复制构造函数,用参数表中给出的已有顺序表初始化新建的顺序表
maxSize = L.Size();
last = L.Length()-1;
T value;
data = new T[maxSize];//创建顺序表储存数组
if(data == NULL){
cout<<"动态分配错误!"<<endl;
}
for(int i =1;i<=last-1;i++){
L.GetData(i, value);
data[i-1] = value;
}
}
调整顺序表空间大小
template <class T>
inline void SeqList<T>::reSize(int newSize){
//私有函数,扩充顺序表的储存数组空间的大小,新数组的元素个数为newSize.
if(newSize <= 0){
cout<<"无效数组的大小!"<<endl;
}
if(newSize != maxSize){
T *newarray = new T[newSize];
if(newarray == NULL){
cout<<"储存分配错误!"<<endl;
}
int n = last+1;
T *srcptr = data;//源数组的首地址
T *desptr = newarray;//目的数组的首地址
while(n--){//复制
*desptr++ = *srcptr++;
}
delete []data;//删除老数组
data = newarray;
maxSize = newSize;//复制新数组
}
}
搜索和定位操作
template <class T>
inline int SeqList<T>::Search(T x)
{
//搜索函数:在表中顺序搜索与给定值x匹配的表项,找到则函数返回该表项是第几个元素
//否则返回0,表示搜索失败
for(int i=0;i<=last;i++){
if(data[i] == x)
return i+1;
}
return 0;
}
template <class T>
inline int SeqList<T>::Locate(int i)
{
//定位函数:返回第i(1<=i<=lat+1)个表项的位置,否则函数返回0,表示定位失败
if(i>=1 && i<last+1){
return i;
}
else return 0;
}
插入与删除操作
template <class T>
inline bool SeqList<T>::Insert(int i, T& x)//插入x在第i个表项之后
{
//将新元素x插入到第i(0<=i<=last+1)个表项之后。函数返回插入成功的信息,若插入成功返回true,否则返回false.
//i=0时虚拟的,实际上是插入到第1个元素的位置。
if(last == maxSize - 1){
return false;//表满,不能插入
}
if(i<0 || i > last+1)
{
return false;//参数i不合理,不能插入
}
for(int j=last;j>=i;j--)
{
data[j+1]=data[j];//一次后移,空出第i号位置
}
data[i] = x;//插入
last++;//最后位置加一
return true;
}
template <class T>
inline bool SeqList<T>::Remove(int i, T& x)//删除第i个表项之后,通过x返回表项的值
{
//从表中删除第i(0<=i<=last+1)个表项,通过引用型参数x返回删除的元素值。函数返回删除成功的信息,删除成功返回true,删除失败返回false
if(last == -1){
return false;//表空,不能删除
}
if(i<1 || i>last+1){
return false;//参数i不合理,不能删除
}
x=data[i];//储存删除的元素
for(int j=i;j<=last;j++)
{
data[j-1] = data[j];//依次前移,填补
}
last--;//最后位置减一
return true;
}
顺序表的性能分析
顺序表所有操作的实现中,最复杂、最耗时的就是搜索、插入和删除运算的实现代码。分析顺序表的性能,主要是分析这3个操作的实现代码的时间复杂性。
int search(T& x)是顺序表的顺序搜索算法。 其主要思想是:
从表的开始位置起,根据给定值x,逐个与表中各表项的值进行比较。 若给定值与某个表项的值相等,则算法报告搜索成功的信息并返回该表项的位置;若查遍表中所有的表项,没有任何一个表项满足要求,则算法报告搜索不成功的信息并返回0(必要的话,可改一下算法,返回新表项应插人的位置)。
搜索算法的时间代价用数据比较次数来衡量。 在搜索成功的情形下,顺序搜索的数据比较次数可做如下分析。 若要找的正好是表中第1个表项,数据比较次数为1,这是最好情况;若要找的是表中最后的第n个表项,数据比较次数为n(设表的长度为n),这是最坏的情况 。若要计算平均数据比较次数,需要考虑各个表项的搜索概率p及找到该表项时的数据比较次数pip_ipi.搜索的平均数据比较次数ACN(average comparing number)为
ACN=∑i=1npi×ci\sum_{i=1}^n {p_i}\times c_i∑i=1npi×ci
计算平均数据比较次数是为了了解对表操作的整体性能。若考虑相等概率的情形。搜索各表项的可能性相同,有p1p_1p1=p2p_2p2=…=pnp_npn=1n\frac1 nn1,且搜索第1个表项的数据比较次数为1,搜计算平均值是为了解算法对表操作的整体性能。 若仅考虑相等概率的情形。搜索各表索第2个表项的数据比较次数为2,搜索第i号表项的数据比较次数为i,则
ACN=1n∑i=1ni=1n(1+2+3+...+n)==1+n2\frac1 n\sum_{i=1}^ni=\frac1 n(1+2+3+...+n)==\frac{1+n} 2n1∑i=1ni=n1(1+2+3+...+n)==21+n
即平均要比较n+12\frac{n+1} 22n+1个表项。
分析顺序表的插入和删除的时间代价主要看循环内的数据移动次数
在将新表项插入到第i个表项(0≤\leq≤ i ≤\leq≤n)后面时,必须从后向前循环,逐个向后移动n-i个表项。 因此,最好的情形是在第n个表项后追加新表项,移动表项个数为0;最差情形是在第1个表项位置插人新表项(视为在第0个表项后面插入),移动表项个数为n;平均数据移动次数AMN(average moving number)在各表项插入概率相等时为
AMN=1n+1∑i=0n(n−i)=1n+1n(n+1)2=n2\frac1 {n+1}\sum_{i=0}^n{(n-i)}=\frac1 {n+1}\frac{n (n+1)} 2=\frac n 2n+11∑i=0n(n−i)=n+112n(n+1)=2n
即就整体性能来说,在插入时有n+1个插入位置,平均移动n2\frac n 22n个表项!
在删除第i个表项(1≤\leq≤ i ≤\leq≤n)时,必须从前向后循环,逐个移动n一i个表项。 因此,最好的情形是删去最后的第n个表项,移动表项个数为0;最差情形是删去第1个表项,移动项个数为n-1;平均数据移动次数AMN在各表项删除概率相等时为
AMN=1n∑i=1n(n−i)=1nn(n−1)2=n−12\frac1 n\sum_{i=1}^n{(n-i)}=\frac1 {n}\frac{n (n-1)} 2=\frac {n-1} 2n1∑i=1n(n−i)=n12n(n−1)=2n−1
就整体性能来说,在删除时有n个删除位置,平均移动(n-1)/2个表项。
以上是C++顺序表使用过程中最常用的主要操作,相关完整代码已经push到GitHub,需要的小伙伴自行clone,如果觉得还不错的话,欢迎Star,这里是传送门C++顺序表,除此之外,想要了解更多的C,C++,Java,Python等相关知识的童鞋,欢迎来我的博客相逢的博客,我们一起讨论!接下来我会更新C语言链式结构实现线性表,敬请期待!
C++语言实现顺序表的更多相关文章
- C语言实现顺序表
C语言实现顺序表代码 文件SeqList.cpp #pragma warning(disable: 4715) #include"SeqList.h" void ShowSeqLi ...
- C语言实现顺序表(顺序存储结构)
顺序表(顺序存储结构)及初始化过程详解 顺序表,全名顺序存储结构,是线性表的一种.通过<线性表>一节的学习我们知道,线性表用于存储逻辑关系为"一对一"的数据,顺序表自然 ...
- java语言建立顺序表
package datastructure; //线性表 public interface IList { public void clear(); public boolean isEmpty(); ...
- C语言实现顺序表的基本操作(从键盘输入 生成线性表,读txt文件生成线性表和数组生成线性表----三种写法)
经过三天的时间终于把顺序表的操作实现搞定了.(主要是在测试部分停留了太长时间) 1. 线性表顺序存储的概念:指的是在内存中用一段地址连续的存储单元依次存储线性表中的元素. 2. 采用的实现方式:一段地 ...
- c语言实现--顺序表操作
经过三天的时间终于把顺序表的操作实现搞定了.(主要是在测试部分停留了太长时间) 1;线性表顺序存储的概念:指的是在内存中用一段地址连续的存储单元依次存储线性表中的元素. 2;采用的实现方式:一段地址连 ...
- 顺序表及其多种实现方式 --- C/C++
所谓顺序表,即线性表的顺序存储结构.下面给出的是数据结构---线性表的定义. ADT List{ 数据对象: 线性表的数据对象的集合为{a1,a2,a3,...,an},每个元素的类型为ElemTyp ...
- C++实现动态顺序表
顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构.这样的存储方式使得线性表逻辑上相邻的元素,其在物理存储单元中也是相邻的.只要知道了第一个元素的存 ...
- 动态顺序表(C++实现)
顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构. 这样的存储方式使得线性表逻辑上相邻的元素,其在物理存储单元中也是相邻的.只要知道了第一个元素的 ...
- 数据结构C语言版--动态顺序表的基本功能实现(二)
/* * 若各个方法结构体变量参数为: &L(即地址符加变量)则结构体变量访问结构成员变量时使用"." * 若为:*L(即取地址符加变量)则结构体变量访问结构体成员变量使用 ...
随机推荐
- 《Java8 Stream编码实战》正式推出
当我第一次在项目代码中看到Stream流的时候,心里不由得骂了一句"傻X"炫什么技.当我开始尝试在代码中使用Stream时,不由得感叹真香. 记得以前有朋友聊天说,他在代码中用了 ...
- 简单认识并使用JavaScript【供后端人员作为了解】
JS(JavaScript)Web的脚本语言 脚本语言:无法独立执行,必须嵌入到其他语言当中结合使用 作用:控制页面特效展示 注:JavaScript没有访问系统的权限,并且JavaScript和Ja ...
- 【简说Python WEB】flask-mail电子邮件异步Asynchronous
系统环境:Ubuntu 18.04.1 LTS Python使用的是虚拟环境:virutalenv Python的版本:Python 3.6.9 flask-mail电子邮件异步Asynchronou ...
- MySQL 【进阶查询】
数据类型介绍 整型 tinyint, # 占1字节,有符号:-128~127,无符号位:0~255 smallint, # 占2字节,有符号:-32768~32767,无符号位:0~65535 med ...
- 自定义上下文菜单,contextmenu事件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 《自拍教程51》Python_adb批量生成App版本表格
案例一:版本在软件研发阶段是很重要的, 不同的版本, 已修复的Bug也不一样, 所实现的功能不一样, Android终端产品正式版本发布前,项目经理除了确保系统版本确定无误外, 还会逐个验证所搭载的所 ...
- vue命令式组件和插件编写
一直在写各种业务,好多基本用法都忘记了,回顾一下: 一.vue各种UI库里的命令式组件比如element-ui里Notification组件,可以这样调用 this.$notify({ title: ...
- 【opencv系列04】OpenCV4.X图形绘制
一. 基本图形绘制 1. 基本函数与参数 cv2.line(): 线 cv2.circle(): 圆 cv2.rectangle(): 矩形 cv2.ellipse(): 椭圆 cv2.putText ...
- Python第三章-输入输出和运算符
输入输出和运算符 一.输入和输出 1.1 输出 `print()`函数用来向终端输出数据(其实也可以向文件输出数据,后面再讲) 可以传递多个参数,则输出的时候 python 会把多个参数的值用空格隔开 ...
- 浅尝Go语言GC
大家好,我是小栈君,因为个人和工作的缘故,所以拖更了一点时间,但是关于拖更的内容小栈君会在后续的时间中补回来,还希望大家继续支持和关注小栈君.当然,在国内疫情稍微减缓的情况下,小栈君在这里也多说两句, ...