首先,我们需要了解什么是线性表——线性表是具有相同数据类型的n(n>=0)个数据元素的有限序列。之前提到,一个数据元素可以由多个数据项组成,在这种情况下, 我们将数据元素称之为记录,含有大量记录的线性表叫做文件。
值得一提的是,线性表是线性结构的代表。而线性结构的特点在线性表中也能体现:
(1)存在唯一一个被叫做“第一个”的数据元素。
(2)存在唯一一个被叫做“最后一个”的数据元素。
(3)除第一个之外,集合中每一个数据元素都有一个”前驱“。
(4)除最后一个之外,集合中每一个数据元素都有一个”后继“。
与课本不同的是,我希望现代大家了解一下线性表的循序表示和实现,线性表的顺序表示指的是用一组地址了连续的存储单元一次存储线性表的数据元素(顺序存储)。
而存储地址的申请,可以使用动态分配的方式,C语言中可以用malloc、free函数申请、释放存储空间。
L.data=(ElemType*) malloc (sizeof (ElemType)* InitSize )
malloc返回一个指针, malloc函数的参数
返回时强制转换为你定义的指针 指明要分配多大内存
通常情况下 我们用数组来表述线性表:
#define LIST_INIT_SIZE 100 //线性表存储空间初始量
#define LISTINCREMENT 10 //线性表存储空间的分配增量
typedef struct{ //定义一种数据类型,叫做SqList(线性表)
ElemType *elem ; //定义存储空间的基地址(指针)
int length; //当前线性表长度
int listsize;//当前分配的存储容量(字节)
}SqList;
在这里我们温习一下define和typedef(仅在本文中的应用性质):
define,宏定义,C语言中 预处理命令 一种。分为无参宏定义和带参宏定义。
无参宏定义 的一般形式为:#define 宏名 字符串;
带参宏定义 的一般形式为:#define 宏名(参数表) 字符串;
1) typedef基本数据类型取“别名”
2) typedef为自定义数据类型取“别名”3) typedef为数组取“别名”
4) typedef为指针取“别名”
接下来,向大家正式介绍线性表的基本操作:(完整代码看下半章)
InitList(SqList &L) 构造一个空的线性表
具体实现为(相关数据起名同上文代码一致):
void InitList(SqList &L){ //创建新线性表
L.elem=(int*)malloc(sizeof(int)*LIST_INIT_SIZE);//为新线性表分配空间
if(!L.elem){ //做判断,分配失败返回error
printf("error\n");
}
printf("输入表的长度:");
scanf("%d",&L.length);
printf("输入%d的个数:",L.length);
for(int i=0;i<L.length;i++)
scanf("%d",&L.elem[i]);
return;
}
GetElem(SqList &L) 按位查找 (用e返回线性表L中第i个元素的值)
*有一点需要注意,在查找,删除两个操作过程中,我认为可以分为两种,一种是按位进行操作,一种是按值进行操作。当然教材中可能只有一种,大家自行领悟。
按值查找和按位查找的区别就是:前者给出元素的值,我们程序返回该值的位置;后者给出值得位置,我们输出这个值。
// GetElem(SqList &L,int i,int &e)书中可能使用这种形式,我不习惯改用下面这种
void GetElem(SqList &L){//按位查找 (用e返回线性表L中第i个元素的值)
int i;
int e;
printf("请输入按位查找所要查找的元素位置:\n");
scanf("%d",&i);
if(i<1||i>L.length){
printf("error\n");
}
e=L.elem[i-1];
printf("%d",&e);
}
LocateElem(SqList &L) 按值查找 (用i返回线性表L中e元素的位置)
void LocateElem(SqList &L){//按值查找 (用i返回线性表L中e元素的位置)
int e;
int i;
printf("请输入按值查找所要查找的元素的值:\n");
scanf("%d",&e);
for(i=0;i<L.length;i++){
if(L.elem[i]==e){
printf("查找成功,查找元素为第%d位",i+1);
printf("\n");
return ;
}//if
}//for
printf("查找失败!");
printf("\n");
}
void ListInsert(SqList &L) 在线性表L第i个位置插入元素e
void ListInsert(SqList &L){//在线性表L第i个位置插入元素e
int i;
int e;
printf("请输入插入值的位置:\n");
scanf("%d",&i);
printf("请输入插入元素的值:\n");
scanf("%d",&e);
printf("在顺序线性表中第%d个位置之前插入新的元素%d\n",i,e);
int *p;
int *q;
if(i<1||i>L.length){
printf("error\n");
}
p=&(L.elem[i-1]);
for(q=&(L.elem[L.length-1]);q>=p;q--){
*(q+1)=*q;
}
*p=e;
++L.length;
}
ListDelete1(SqList &L) 删除某个元素 (按位置删除某个元素,返回这个元素的值)
void ListDelete1(SqList &L){ //删除某个元素 (按位置删除某个元素,返回这个元素的值)
int i;
printf("请输入删除元素的位置:\n");
scanf("%d",&i);
if(i<1||i>L.length){ //判断输入i是否合格
printf("error\n");
}
else{
int e;
e=L.elem[i-1];
int *p;
int *q;
p=&(L.elem[i-1]);
q=&(L.elem[L.length-1]);
for(p;p<=q;p++){
*p=*(p+1);
}
--L.length;
printf("删除元素的值为%d\n",e);
}
}
ListDelete2(SqList &L) 删除某个元素 (按值删除某个元素,返回这个元素的位置)
void ListDelete2(SqList &L){ //删除某个元素 (按值删除某个元素,返回这个元素的位置)
int i;
int e;
printf("请输入删除元素的值:\n");
scanf("%d",&e);
int k=L.length;
for(int j=1;j<=k;j++){
if(L.elem[j-1]==e){
int *p;
int *q;
p=&(L.elem[j-1]);
q=&(L.elem[L.length-1]);
for(p;p<=q;p++){
*p=*(p+1);
}
--L.length;
printf("删除元素的值的位置为%d\n",j);
return;
}
}
printf("error\n");
}
对于插入删除等操作的具体原理讲解请看03(下)
下一节:线性表(下)
个人原创要点总结,部分内容包含个人见解,如有错误请指出!!!