六.线性表的类型定义
- 基本操作
- lnitList(&L) (lnitalization List)
- 操作结果:构造一个空的线性表L
- lnitList(&L) (lnitalization List)
七.线性表的顺序表示和实现
- 线性表的顺序表示又称顺序存储结构或顺序映像
- 顺序存储
- 定义
- 把逻辑上相邻的数据元素存储在物理上相邻的存储单元中的存储结构(简单来说,逻辑上相邻,物理上也相邻)
- 特点
- 以物理位置相邻表示逻辑关系,任一元素均可随机存取。
- 区别
- 顺序表元素与数组元素同样有地址连续,依次存储,随机存储,类型相同的特点。线性表长可变化,可以删除以及插入。数组长度不可以动态定义。
- 相关概念
- 线性表的第一个数据元素的存储未知,叫做线性表的起始位置或基地址。
- 定义
- 顺序存储
- 顺序表标准模板
#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量
typedef struct{
ElemType elem[LIST_INIT_SIZE];
int length; //当前长度
}SqList;
八.类c语言有关操作补充
-
数组定义
-
数组静态分配
typedef struct{
ElemType data[MaxSize];
int length;
}SqList;
-
数组动态分配
typedf struct{
ElemType *data
int length;
}SqList;
-
内存动态分配
SqList L;
L.data=(ElemType*)malloc(sizef(ElemType)*MaxSize);
- malloc(m)函数,开辟m字节长度的地址空间,并返回空间的地址。
- sizeof(x)运算,计算变量x的长度。
- free(p)函数,释放指针p所指变量的存储空间,彻底删除一个变量。
-
C++的动态存储分配
new 类型名T(初值列表)
功能:
申请用于存放T类型对象的内存空间,并依初值列表赋以初值
结果值:
成功:T类型的指针,指向新分配的内存
失败:0(NULL)
delete 指针P
功能:
释放指针P所指向的内存,P必须是new操作的返回值
-
C++中的参数传递
- 函数调用时传送给形参表的实参必须与形参三个一致
- 类型、个数,顺序
- 参数传递的两种方式
- 传值方式
- 把实参的值传送给函数局部工作区相应的副本中,函数使用这个副本执行必要的功能。函数修改的副本的值,实参不变
- 传地址
- 参数为指针变量
- 形参变化影响实参
- 参数为引用类型(c++才有)
- 传递引用给函数与传递指针的效果一样的,形参变化实参也发生变化。
- 引用类型作形参,在内存中没有产生实参的副本,直接对实参操作。
- 一般变量做参数,形参与实参占用不通的村单元,所以形参变量的值是实参变量的副本,所以传递数据量较大时,引用比用一般变量传递参数的诗句和空间效率都好。
- 指针参数也可有达到引用的效果,但在被调函数中需要重复使用“*指针变量名”的形式运算,容易产生错误且程序的阅读性较差,在主调函数的调用点处必须用变量的地址做实参。
- 参数为数组名
- 传递的是数组的首地址
- 对形参数组所做的任何改变都讲反映到实参数组中
- 参数为指针变量
- 传值方式
- 函数调用时传送给形参表的实参必须与形参三个一致
九.线性表的顺序表示和实现
逻辑结构与物理位序差1
-
操作算法中用到的预定义常量和类型
-
函数结构状态代码
- #define TRUE 1
- #define FALSE 1
- #define OK 1
- #define ERROR 1
- #define INFEASIBLE -1
- #define OVERFLOW -2
-
线性表的实现
-
线性表L的初始化(参数用引用)
Status InitList_Sq(SqList &L) //构建一个空的顺序表L
{
L.elem=new ElemType[MAXSIZE]; //分配空间
if(!L.elem)exit(OVERFLOW); //存储分配失败
L.length=0; //空表长度0
return OK;
}
-
销毁线性表L
void DestoryList(SqList &L)
{
if(L.elem)delete L.elem;
}
-
清空线性表L
void ClearList(SqList &L)
{
L.Length=0;
}
-
求线性表L的长度
int Getlength(SqList L)
{
return(L.length);
}
-
判断线性表L是否空
int lsEmpty(SqList L)
{
if(L.length==0)return 1;
else return 0;
}
-
顺序表的取值
int GetElem(SqList L,int i,ElemType &e)
{
if(i<1||i>L.length)
return ERROR;
e=L.elem[i-1];
return OK;
}
-
顺序表的查找
- 在线性表L中查找与指定值e相同的数据元素的位置
- 从表的一端开始,逐个进行记录的关键字和给定值的比较。找到,返回改元素位置序号,没找到,返回0
int LocatElem(SqList,ElemType e)
{
for(i=0;i<L.length;i++) //在线性表L中查找值为e的数据原神,返回序号
if(L.elem[i]==e) //查找成功,返回序号
return i+1;
return 0; //查找失败,返回0
}
//while语句来实现
int LocatElem(SqList,ElemType e)
{
i=0;
while(i<L.length&&L.elem[i]!=e)i++;
if(i<L.length)
return i+1;
return 0;
}
-
顺序表的插入
- 判断插入位置i是否合法
- 判断顺序表的存储空间是否已满,若已满返回ERROR
- 将n到i位的元素依次向后移动一个位置,空出i个位置
- 将要插入的新元素e放入第i个位置
- 表长加1,插入成功返回OK
Status ListInsert_Sq(SqList &L,int i,ElemType e)
{
if(i<1||i>L.length+1)
return ERROR; //i值不合法
if(L.length==MAXSIZE)
return ERROR; //当前存储空间已满
for(j=L.length-1;j>=1;J--)
L.ele[j+1]=L.elem[j]; //插入位置及之后的元素后移
L.elem[i-1]=e; //将新元素e放入第i个位置
L.length++; //表长增1
return OK;
}
-
顺序表的删除
- 判断插入位置i是否合法
- 将要删除的元素保留在e中
- 将i+1到n位的元素依次向前移动一个位置,
- 表长减1,插入成功返回OK
Status ListDelete_Sq(SqList &L,int i)
{
if(i<1||i>L.length)
return ERROR; //i值不合法
for(j=i;j<=L.length-1;j++)
L.elem[j-1]=L.elem[j]; //被删除元素之后的元素前移
L.length--; //表长减1
return OK;
}
十.顺序表小结
-
顺序表特点
- 利用数据元素的存储位置表示线性表中相邻数据元素之间的前后关系,既线性表的逻辑结构和存储结构一致
- 这种存取元素的方式被称为随机存取法
- 在访问线性表时,可以快速计算出任何一个数据元素的存储地址,可以粗略地认为,访问每个元素所话时间相等
-
顺序表的操作算法分析
-
时间复杂度
- 查找、插入、删除算法的平均时间复杂度为O(n)
-
空间复杂度
- 顺序表操作算法的空间复杂度S(n)=O(1),既没有占用辅助空间
-
顺序表的优缺点
- 优点
- 存储密度大(结点本身所占存量/结点结构所占存储量)
- 可以随机存储表中任一元素
- 缺点
- 在插入、删除某个元素时,需要移动大量元素
- 浪费存储空间
- 属于静态存储形式,数据元素的个数不能自由扩充
- 优点
-