《数据结构》个人笔记3
线性表的定义和特点
1.线性表的定义:
由n个数据特性相同的元素构成的有限序列
2.线性表的特点:
(1).存在唯一的一个被称为“第一个”的数据元素;
(2).存在唯一一个被称为“最后一个”的数据元素;
(3).除第一个外,结构中的每个数据元素均只有一个前驱;
(4).除最后一个外,结构中的每个数据元素均只有一个后继。
线性表的顺序表示和实现
1.线性表的顺序表示:
用一组地址连续的存储单元依次存储线性表的数据元素,这种存储结构也被称为顺序表。
2.顺序表的特点:
1.逻辑上:是相邻的数据元素。
2.物理上:次序也是相邻的。
3.在C语言中用动态分配一维数组来表示线性表
程序3-1
#define MAXSIZE 100 //顺序表可能到达的最大长度
typedef struct
{
ElemType *elem; //存储空间的基地址
int length; //当前长度
}SqList; //顺序表的结构类型为SqList
1.数组空间初始化完成后,数组指针elem指示顺序表的基地址,数组空间大小为MAXSIZE。
2.元素类型定义中的ElemType数据类型是为了描述统一而自定的,在实际应用中,用户根据具体定义表中的数据元素的数据类型,既可以是基本数据类型,也可以是构造数据类型(如struct结构体类型)。
3.length表示顺序表中当前数据元素的个数。因为C语言数组的下标是从0开始的,而位置序号是从1开始的,所以要区分元素的位置序号和该元素在数组中的下标位置之间的对应关系,根据元素a1、a2、a3、…、an依次存放在数组elem【0】、elem【1】、…、elem【length-1】中。
4.顺序表中的基本操作的实现
当线性表以上述定义的顺序表表示时,某些操作很容易实现。因为表的长度是顺序表的一个属性,所以可以通过返回length的值实现求表长的操作,通过判断length的值是否为0判断表是否为空。
1.初始化
顺序表的初始化操作其实就是构造一个空的顺序表。
程序3-2
Status InitList(SqList &L)
{//构造一个空的顺序表L
L.elem = new Elemtype[MAXSIZE]; //为顺序表分配一个大小为MAXSIZE的数组空间
if(!L.elem) exit(OVERFLOW); //存储分配失败退出
L.length = 0; //空表长度为0
return OK;
}
动态分配线性表的存储区域可以更加有效地利用系统地资源,当不需要该线性表时,可以使用销毁操作及时释放占用的存储空间。
2.取值
由于顺序存储结构有着随机存取的特点,所以我们可以直接通过数组下标定位得到,elem[i-1]单元存储第i个数据元素。
思路:
1.判断指定位置是否合理,若不合理,返回ERROR。
2.若i合理,则将第i个数据元素L.elem[i-1]赋给参数e,通过e返回第i个数据元素的传值。
程序3-3
Status GetElem(SqList L,int i,ElemRype &e)
{
if (i<1||i>L.length) return ERROR;
e=L.elem[i-1];
return OK;
}
3.查找
思路:
1.从第一个元素开始找起,将每个元素和e对比,若找到与e相同的元素L.elem[i],则代表查找成功,返回该元素序号i+1。
2.若查找了整个顺序表都没找到与e相同的元素,则代表查找失败,返回0。
程序3-4
int LocateElem(Sqlist L,ElemType e)
{//在顺序表L里查找值为e的数据元素,返回其序号
for(i=0;i<L.length;i++)
if (L.elem[i]==e) return i+1;
return 0;
}
4.插入
思路:
1.判断插入位置i是否合法(i值得合法范围为1<=i<=n+1),若不合法则返回ERROR。
2.判断顺序表得存储空间是否已经满了,若满了,则返回ERROER。
3.将第n个至第i个位置的元素依次向后移动一个位置,空出第i个位置(i=n+1时无需移动)。
4.将要插入的新元素放入第i个位置。
5.表长加1。
程序3-5
Status ListInsert(SqList &L,int i,ElemType e)
{
if(i<1||i>(L.length+1)) return ERROR;
if(L.length==MAXSIZE) return ERROR;
for( int j=L.length-1;j>=i-1;j--)
{
L.elem[j+1]=L.elem[j];
}
L.elem[i-1]=e;
++L.length;
return OK;
}
上述算法没有处理表的动态扩充,因此当表长已经到达预设的最大空间时,则不能再插入元素》。
5.删除
思路:
1.判断删除位置i是否合法(合法值为1<=i<=n),若不合法则返回ERROR。
2.将第i+1个元素至第n个元素依次向前移动一个位置(i=n时无需移动)。
3.表长减1。
程序3-6
Status ListDelete(SqList &L,int i)
{
if((i<1)||(i>L.length)) return ERROR;
for(j=i;j<=L.length-1;j++)
{
L.elem[j-1]=L.elem[j];
}
--L.length;
return OK;
}
总结
顺序表可以随机存取表中的任一元素,其存储位置可以用简单、直观的公式来表示,但是,这一特点也造成了一定的麻烦,在做插入或删除时,可能需要动用大量的元素。另一方面,由于数组有长度相对固定的静态特性,当表中数据元素个数较多且变化较大时,操作相对复杂,会导致存储空间的浪费。