一、线性表的定义
线性表(List):零个或多个数据元素的有限序列。线性表的数据集合为{a1,a2,…,an},假设每个元素的类型均为DataType。其中,除第一个元素a1外,每一个元素有且只有一个直接前驱元素,除了最后一个元素an外,每一个元素有且只有一个直接后继元素。数据元素之间的关系是一对一的关系。在较复杂的线性表中,一个数据元素可以由若干个数据项组成。在这种情况下,常把数据元素称为记录,含有大量记录的线性表又称为文件
二、线性表代码
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define ERROR 0
#define OK 1
#define True 1
#define False 0
#define LIST_INIT_SIZE 5 /*初始分配的顺序表长度*/
#define LISTINCREAMENT 5 /*溢出时,顺序表长度的增量*/
typedef int ElemType; /*定义顺序表数据元素的类型*/
typedef int Status; /*定义函数的类型,其值是函数结果状态代码*/
typedef struct Sqlist{
ElemType *elem; /*顺序表存储空间的基地址(注意顺序表从下标1开始存放数据元素)*/
int length; /*顺序表的当前长度*/
int listsize; /*当前分配的存储空间容量(以sizeof(ElemType)为单位)*/
}Sqlist;
Status InitList_sq(Sqlist &L); // 初始化线性表L
Status CreateList_sq(Sqlist &L,int n); // 建立线性表L任意顺序
Status ListInsert_sq(Sqlist &L,int i,ElemType e);//插入在线性表L中第i个数据元素之前插入数据元素e
void PrintList_sq(Sqlist L); //输出顺序表的元素
Status ListDelete_sq(Sqlist &L,int i,ElemType &e); /*删除第i个元素*/
int ListLocate_sq(Sqlist L,ElemType e); /*查找值为e的元素*/
void DestroyList_sq(Sqlist &L);//销毁线性表L
void ClearList_sq(Sqlist &L);//清空线性表L
Status ListEmpty_sq(Sqlist L);//判断线性表L是否为空
int ListLength_sq(Sqlist L);//获取表长
Status GetElem_sq(Sqlist L,int i,ElemType &e);//取值(根据位置i获取相应位置数据元素的值)
Status InitList_sq(Sqlist &L)// 初始化线性表L
{
L.elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!L.elem)exit(False);
L.length=0;
L.listsize=LIST_INIT_SIZE;
return OK;
}/*InitList*/
Status CreateList_sq(Sqlist &L,int n)// 建立线性表L
{
ElemType e;
int i;
for(i=1;i<=n;i++)
{
printf("please input number %d: ",i);
scanf("%d",&e);
if(!ListInsert_sq(L,i,e))return ERROR; //需要判断,否则值无效
}
return OK;
}/*CreateList*/
void PrintList_sq(Sqlist L)//输出顺序表中的元素
{
int i;
for(i=1;i<=L.length;i++)
printf("%d ",L.elem[i]);
printf("\n");
}/*PrintList*/
Status ListInsert_sq(Sqlist &L,int i,ElemType e)//插入在线性表L中第i个数据元素之前插入数据元素e
{
int * newbase, *p, *q;
if(i < 1 || i > L.length+1)
return ERROR;
if(L.length >= L.listsize-1)
{
newbase = (ElemType *) realloc(L.elem,
(L.listsize + LISTINCREAMENT) * sizeof(ElemType));
if(!newbase)exit(False);
L.elem = newbase;
L.listsize +=LISTINCREAMENT;
}
q = &(L.elem[i]);
for(p = &(L.elem[L.length]); p >= q; --p)
*(p + 1) = *p;
*q = e;
++L.length;
return OK;
}/*ListInsert_sq*/
Status ListDelete_sq(Sqlist &L,int i,ElemType &e)//在顺序表中删除第i个元素
{
int *p, *q;
if(i < 1 || i > L.length)
return ERROR;
p=&(L.elem[i]);
e=*p;
q=L.elem+L.length;
for(++p;p<=q;++p)
*(p-1)=*p;
--L.length;
return OK;
}/* ListDelete_sq */
int ListLocate_sq(Sqlist L,ElemType e)//在顺序表中查找指定值元素,返回其序号
{
for(int i=1;i<=L.length; i++)
{
if( e==L.elem[i])return i;
}
return ERROR;
}/* ListLocate_sq */
void DestroyList_sq(Sqlist &L)//销毁线性表L
{
free(L.elem);
}/* DestroyList_sq */
void ClearList_sq(Sqlist &L) //清空线性表L
{
L.elem=NULL;
L.length=0;
L.listsize =0;
}/* ClearList_sq */
Status ListEmpty_sq(Sqlist L)//判断线性表L是否为空
{
if(L.length==0)
return True;
else return False;
}/* ListEmpty_sq */
int ListLength_sq(Sqlist L)//获取表长
{
return L.length;
}/* ListLength_sq */
Status GetElem_sq(Sqlist L,int i,ElemType &e)//取值(根据位置i获取相应位置数据元素的值)
{
if(i < 1 || i > L.length) return ERROR;
e = L.elem[i];
return OK;
}/* GetElem_sq */
int main(){
Sqlist sl;
int n,m,k;
ElemType e;
printf("please input n:"); /*输入顺序表的元素个数*/
scanf("%d",&n);
if(n>0){
printf("\n1-建立顺序表:\n");
InitList_sq(sl); //InitList_sq(&sl);
CreateList_sq(sl,n);
printf("\n2-输出顺序表的元素:\n");
PrintList_sq(sl);
printf("\n请输入待插入数据的位置和值(location,data):");
scanf("%d,%d",&m,&e);
if( ListInsert_sq(sl,m,e) )
{
printf("\n3-输出顺序表的元素:\n");
PrintList_sq(sl);
printf("\n");
}
printf("\n");
printf("\n请输入待删除数据的位置:");
scanf("%d",&m);
if( ListDelete_sq(sl,m,e) )
{
printf("\n删除的数据为:%d\n",e);
printf("\n4-输出顺序表的元素:\n");
PrintList_sq(sl);
printf("\n");
}
printf("\n");
printf("\n请输入待查找的数据:");
scanf("%d",&e);
m=ListLocate_sq(sl,e);
if(m==0) printf("\n该数据不在顺序表中\n");
else printf("\n该数据在顺序表中第%d个位置\n",m);
printf("\n");
if(ListEmpty_sq(sl)) printf("\n该顺序表为空\n");
else
{
printf("\n该顺序表非空\n");
printf("\n该顺序表表长为%d\n",ListLength_sq(sl));
}
printf("\n");
printf("\n请输入待取值的数据的位置:");
scanf("%d",&m);
k=GetElem_sq(sl,m,e);
if(k==0) printf("\n输入位置值不合理\n");
else printf("\n在顺序表中第%d个位置的数据值为%d\n",m,e);
printf("\n");
printf("\n清空顺序表......\n");
ClearList_sq(sl);
if(ListEmpty_sq(sl)) printf("\n该顺序表为空\n");
else
{
printf("\n该顺序表非空\n");
printf("\n该顺序表表长为%d\n",ListLength_sq(sl));
}
printf("\n");
printf("\n销毁顺序表......\n");
DestroyList_sq(sl);
if(sl.elem==NULL) printf("\n顺序表已销毁\n");
}
else
printf("ERROR");
return 0;
}
小结
1、顺序表时间复杂度从以上代码可以很明显的看出,线性表的顺序存储结果在读、存数据是的时间复杂度是O(1),插入、删除操作的时间复杂度是O(n)。
2、顺序表的优缺点 ,优点:无须为表中元素之间的逻辑关系而增加额外的存储空间;可以快速的存取表中任一位置的元素。缺点:插入和删除操作需要移动大量元素;当线性表长度较大时,难以确定存储空间的容量;造成存储空间的“碎片”。