1、线性表
-
是具有相同特性的数据元素的一个有限序列(a1,a2,…,ai-1,ai,ai+1,…,an)
-
n=0时称为空表
-
其中数据元素的个数n定义为表的长度
-
将非空的线性表(n>0)记作:(a1,a2,…,an)
-
这里的数据元素ai(1≤i≤n)只是一个抽象的符号,其具体含义在不同的情况下可以不同
2、线性表的逻辑特征
- 在非空的线性表,有且仅有一个开始结点a1,它没有直接前趋,而仅有一个直接后继a2
- 有且仅有一个终端结点an,他没有直接后继,而仅有一个直接前趋an-1
- 其余的内部结点ai(2in-1)都有且仅有一个直接前趋ai-1和一个直接后继ai+1
- 线性表是一种典型的线性结构
3、线性表基本操作
-
InitList(&L) (Initialization List)
构造一个空的线性表L
-
DestroyList(&L)
销毁线性表L
初始条件:线性表L已经存在
-
ClearList(&L)
将线性表L重置为空表
初始条件:线性表L已经存在
-
ListEmpty(L)
若线性表L为空表,则返回TURE;否则返回FALSE
初始条件:线性表L已经存在
-
ListLength(L)
返回线性表L中的数据元素个数
初始条件:线性表L已经存在
-
GetElem(L,i,&e);
用e返回线性表L中第i个数据元素的值
初始条件:线性表L已经存在,1 ≤ i ≤ ListLength(L)
-
LocateElem(L,e,compare())
返回L中第1个与e满足compare()的数据元素的位序。若这样的数据元素不存在则返回值为0
初始条件:线性表L已经存在,compare()是数据元素判定函数
-
PriorElem(L,cur_e,&pre_e)
若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败;pre_e无意义
初始条件:线性表L已经存在
-
NextElem(L,cur_e,&next_e)
若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的前驱,否则操作失败;next_e无意义
初始条件:线性表L已经存在
-
ListInsert(&L,i,e)
在L的第i个位置之前插入新的数据元素e,L的长度加一
初始条件:线性表L已经存在,1 ≤ i ≤ ListLength(L)+1
-
ListDelete(&L,i,&e)
删除L的第i个数据元素,并用e返回其值,L长度减一
初始条件:线性表L已经存在,1 ≤ i ≤ ListLength(L)
-
ListTraverse(&L,visited())
依次对线性表中每个元素调用visited() 遍历线性表
初始条件:线性表L已经存在
4、补充操作
-
malloc(m)函数:开辟m字节长度的地址空间,并返回这段空间的首地址
-
sizeof(x)运算:计算变量x的长度
-
free§函数,释放指针p所指变量的存储空间,即彻底删除一个变量
-
new 类型名T(初值列表)
功能:申请用于存放T类型对象的内存空间,并依初值列表赋以初值
结果值:成功:T类型的指针,指向新分配的内存;失败:0(NULL)
int *p1=new int;或 int *p1=new int(10);
-
delete 指针p
功能:释放指针p所指向的内存,p必须是new操作的返回值
delete p1;
-
参数传递
-
函数调用时,形参表的实参与形参类型、个数、顺序一致
-
两种传递方式
传值方式(参数为整型、实型、字符型等)
传地址(参数为指针变量、引用类型、数组名)
-
5、顺序表示
- 定义:把逻辑上相邻的数据元素存储在物理上相邻的存储单元中的存储结构(逻辑上相邻,物理上也相邻)
- 线性表的第1个数据元素a1的存储位置,称作线性表的起始位置或基地址
- 典型的线性表顺序存储结构:依次存储,地址连续——中间没有空出存储单元
- 假设线性表的每个元素需占l个存储单元,则第i+1个数据元素的存储位置和第i个数据元素的存储位置之间满足关系:LOC(ai+1)=LOC(ai)+l
- 优点:任一元素均可随机存取
- 缺点:进行插入和删除操作时,需移动大量的元素,存储空间不灵活
- 随机存取法
- 逻辑位序和物理位序相差1
#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量
typedef struct
{
ElemType elem[LIST_INIT_SIZE];
int length; //当前长度
}
SqList;
eg:多项式的顺序存储
#difine MAXSIZE 1000 //多项式可能达到的最大长度
typedef struct //多项式非零项的定义
{
float p; //系数
int e; //指数
}Polynomial;
typedef struct
{
Polynomial *elem; //存储空间的基地址
int length; //多项式中当前项的个数
}SqList; //多项式的顺序存储结构类型为SqList
eg:图书表的顺序存储
#define MAXSIZE 10000 //图书表可能达到的最大长度
typedef struct //图书信息定义
{
char no[20]; //图书ISBN
char name[50]; //图书名字
float price; //图书价格
}Book;
typedef struct
{
Book *elem; //存储空间的基地址
int length; //图书表中当前图书个数
}SqList; //图书表的顺序存储结构类型为SqList
①线性表的初始化
Status InitList_Sq(SqList &L) //构造一个空的顺序表L
{
L.elem=new ElemType[MAXSIZE]; //为顺序表分配空间
if(!L.elem) exit(OVERFLOW); //存储分配失败
L.length=0; //空表长度为0
return OK;
}
②销毁线性表
void DestroyList(SqList &L)
{
if(L.elem) delete L.elem; //释放存储空间
}
③清空线性表
void ClearList(SqList &L)
{
L.length=0; //将线性表的长度置为0
}
④求线性表长度
int GetLength(SqList L)
{
return(L.length);
}
⑤判断线性表是否为空
int IsEmpty(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; //判断i值是否合理,若不合理,返回ERROR
e=L.elem[i-1]; //第i-1的单元存储着第i个数据
return OK;
}
⑦顺序表的查找
- 在线性表L中查找与指定值e相同的数据元素的位置
- 从表的一端开始,逐个进行记录的关键字和给定值的比较。找到,返回该元素的位置序号,未找到,返回0.
int LocateElem(SqList L,ElemType e) //在线性表L中查找值为e的数据元素,返回其序号
{
for(i=0;i<L.length;i++)
if(L.elem[i]==e) return i+1; //查找成功,返回序号
else return 0; //查找失败,返回0
}
- 平均查找长度ASL(Average Search Length)
- 为确定记录在表中的位置,需要与给定值进行比较的关键字的个数的期望值叫做查找算法的平均查找长度
⑧顺序表的插入
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>=i-1;j--)
L.elem[j+1]=L.elem[j]; //插入位置及之后的元素后移
L.elem[i-1]=e; //将新元素e放入第i个位置
L.lenght++; //表长增1
return 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--; //表长减一
return OK;
}