1.线性表的定义
由零个或多个数据元素组成的有限序列。
用数学语言定义如下:
若线性表记为(a1,...,ai-1,ai,ai+1,...an)则表中ai-1领先于ai,ai领先于ai+1,称ai-1是ai的直接前驱元素,ai+1是ai的直接后继元素。
线性表的个数n>=0,n=0时为空表
2. ADT 线性表(List)
data
线性表的数据对象集合为{a1,a2,。。。an}每个元素的类型为DataType。其中,除第一个元素a1外,每一个元素有且只有一个直接前驱元素,除了最后一个元素an外,每一个元素有且只有一个直接后继元素,数据元素之间的关系是一对一的关系。
operation
InitList(*L):初始化操作,建立一个空的线性表L
ListEmpty(L):判断线性表是否为空表,若线性表为空,返回true,否则返回false
CreateList(*L):创建线性表
PutList(L):打印线性表
ClearList(*L):将线性表清空
GetElem(L,i,*e):将线性表L中的第i个位置元素之返回给e
LocateElem(L,e):在线性表L中查找与给定值e相等的元素,如果查找成功,返回该元素在表中序号表示成功,否则返回0表示失败
ListInsert(*L,i,e):在线性表L中第i个位置插入新元素e
ListDelete(*L,i,*e):删除线性表中第i个位置元素,并用e返回其值
ListLength(L):返回线性表L的元素个数
endADT
3.编码实现
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 20
#define OK 1
#define ERROR -1
enum selection{initList=1,listEmpty,createList,putList,clearList,getElem,locateElem,listInsert,listDelete,listLength};
typedef int ElemType;
typedef struct
{
ElemType data[MAXSIZE];
int length;
}SqList;
//初始化操作,建立一个空的线性表L
void InitList(SqList *L)
{
L->length=0;
printf("initList success!\n");
}
//判断线性表是否为空表,若线性表为空,返回true,否则返回false
void ListEmpty(SqList L)
{
if(L.length==0)
printf("the list is empty!\n");
else
printf("the list is not empty!\n");
}
//创建线性表
void CreateList(SqList *L)
{
int tmp,i=0;
printf("create a list:\n");
printf("please input a number ('#' end):\n");
while(1==(scanf("%d",&tmp)))
{
L->data[i++]=tmp;
L->length++;
}
fflush(stdin);//清空输入缓冲区
printf("create successfully!\n");
}
//打印线性表
void PutList(SqList L)
{
int i;
printf("the list is:\n");
for(i=0;i<L.length;i++)
{
printf("%d->",L.data[i]);
}
printf("the end!");
printf("\n");
}
//清空链表
void ClearList(SqList *L)
{
InitList(L);
}
//将线性表L中的第i个位置元素返回给e
int GetElem(SqList *L,int i,ElemType *e)
{
if(i<=0||L->length<i||L->length==0){
return ERROR;
}
*e=L->data[i-1];
return OK;
}
//在线性表L中查找与给定值e相等的元素,如果查找成功,返回改元素在表中的序号表示成功,否则返回0表示失败
int LocateElem(SqList L,int e)
{
int i;
if(L.length>0)
{
for(i=0;i<L.length;i++)
{
if(L.data[i]==e)
{
return i;
}
}
}
return -1;
}
//在线性表L中第i个位置插入新元素e
int ListInsert(SqList *L,int i,ElemType e)
{
int k;
if(L->length==0||L->length+1<i||i<=0)
{
return ERROR;
}
if(i<=L->length)
{
for(k=L->length;k>=i;k--)
{
L->data[k]=L->data[k-1];
}
}
L->data[i-1]=e;
L->length++;
return OK;
}
//返回线性表L的元素个数
void ListLength(SqList L)
{
printf("线性表的长度为%d\n",L.length);
}
//删除线性表中第i个位置元素,并用e返回其值
int ListDelete(SqList *L,int i,ElemType *e)
{
int k;
if(L->length==0||i>L->length)
return ERROR;
*e=L->data[i-1];
if(i<=L->length)
{
for(k=i;k<L->length;k++)
L->data[k-1]=L->data[k];
}
L->length--;
return OK;
}
void showItems()
{
puts("please input <1-10> to select operation:");
puts("-----------------------------------------------");
puts(" 1>initList 2>listEmpty 3>createList");
puts(" 4>putList 5>clearList 6>getElem");
puts(" 7>locateElem 8>listInsert 9>listDelete");
puts(" 10>listLength");
puts("-----------------------------------------------");
}
int main()
{
SqList L;
while(OK)
{
int t,i,e;
enum selection index;
showItems();
scanf("%d",&t);
while((getchar())!='\n');
index=(enum selection)t;
switch(index)
{
case initList:
InitList(&L);
break;
case listEmpty:
ListEmpty(L);
break;
case createList:
CreateList(&L);
break;
case putList:
PutList(L);
break;
case clearList:
ClearList(&L);
break;
case getElem:
printf("请输入位置:\n");
scanf("%d",&i);
if(GetElem(&L,i,&e)==1)
{
printf("第%d位置的元素为%d\n",i,e);
}
else
{
printf("input error!\n");
}
break;
case locateElem:
printf("请输入元素:\n");
scanf("%d",&e);
if(LocateElem(L,e)>0){
printf("success!\n");
printf("表中%d元素的位置是第%d个\n",e,LocateElem(L,e)+1);
}
else
{
printf("there is no number!\n");
}
break;
case listInsert:
printf("请输入要插入的位置和元素:\n");
scanf("%d",&i);
scanf("%d",&e);
if(ListInsert(&L,i,e)==1)
{
printf("insert success!\n");
}
else{
printf("input error!\n");
}
break;
case listDelete:
printf("请输入要删除的位置和元素:\n");
scanf("%d",&i);
scanf("%d",&e);
if(ListDelete(&L,i,&e)==1)
{
printf("delete success!\n");
}
else
{
printf("input error!\n");
}
break;
case listLength:
ListLength(L);
break;
default:
fputs("error input!\n",stderr);
}
}
return 0;
}
4.分析
在存、读数据时,不管是哪个位置,时间复杂度都是O(1).而在插入或删除时,时间复杂度都是O(n).
它比较适合元素个数比较稳定,不经常插入和删除元素,而更多的操作是存取数据的应用。
5.线性表顺序存储结构的优缺点
优点:
无须为表中的元素之间的逻辑关系而增加额外的存储空间
可以快速的存取表中任意位置的元素
缺点:
插入和删除操作需要移动大量元素
当线性表长度比较大时,难以确定存储空间的容量
容易造成存储空间的“碎片”