您的位置:首页 > 其它

线性表的顺序存储

2015-03-13 09:47 183 查看
线性表的顺序存储,其数据结构以及具体实现详见下面代码,重要知识点全部以注释的形式在代码中展示出来。

/***
线性表的顺序存储结构是一种随机存取的存储结构
在线性顺序表中插入或者删除一个元素,时间都消耗在移动元素上,平均约移动一般的元素,
故ListInsert和ListDelete的时间复杂度都为O(n);
*/
#include<stdio.h>
#include<stdlib.h>
//***************线性表的动态分配顺序存储结构*****************
#defineLIST_INIT_SIZE100//线性表存储空间的初始分配量
#defineLISTINCREMENT10//线性表存储空间的存储增量
typedefstruct
{
int*elem;//数组指针,存储空间基址
intlength;//当前长度
intlistsize;//当前分配的存储容量(以sizeof(int)为单位)
}SqList;

//******************初始化线性表,构造一个空表********************
voidInitList(SqList&L)
{
L.elem=(int*)malloc(LIST_INIT_SIZE*sizeof(int));
if(!L.elem)
{
printf("存储分配失败,任意键退出!\n");
getchar();
exit(1);
}
L.length=0;
L.listsize=LIST_INIT_SIZE;
}

//*********************输出线性表中的数据**************************
voidPrintList(SqListL)
{
int*p=L.elem;//顺序表的开始位置
int*q=L.elem+L.length-1;//顺序表的结束位置
while(p<=q)
{
printf("%d",*p++);
}
}

//*************************线性表的插入****************************
//*******参数i代表插入位置,在第i个之前插入*,故1<=i<=n+1*********
/**
一般情况下,在第i(1<=i<=n)个元素之前插入,需要将第i至n(n-i+1)个元素向后移动一个位置,
若i=n+1,则直接在插入在最后即可
*/
voidListInsert(SqList&L,inti,inte)
{
//在顺序线性表L中的第i个位置之前插入新的元素e
//i的合法值为1<=i<=ListLength(L)+1
if(i<1||i>L.length+1)
{
printf("输入的插入位置不合法,请确定后重新输入!任意键退出\n");
getchar();
exit(1);
}
if(L.length>=L.listsize)
{
//当前存储空间已满,需要增加分配
int*newbase=(int*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(int));
if(!newbase)
{
printf("存储分配失败,任意键退出!\n");
getchar();
exit(1);
}
L.elem=newbase;//新基址
L.listsize+=LISTINCREMENT;//增加存储容量
}
int*q=&(L.elem[i-1]);//q为插入位置
for(int*p=&(L.elem[L.length-1]);p>=q;--p)
{
*(p+1)=*p;//插入位置及其之后的元素右移
}
*q=e;//插入e
++L.length;//表长加1
}

//***************************顺序线性表的删除******************************
/**
参数i代表删除位置,1<=i<=n,和插入时i的取值范围不同
一般情况下,删除第i(1<=i<=n)个元素时需要将从第i+1至第n(n-i)个元素依次向前移动一个位置
*/
voidListDelete(SqList&L,inti)
{
//删除顺序线性表中的第i个元素,i的合法值为1<=i<=ListLength(L)
if(i<1||i>L.length)
{
printf("输入的删除位置不合法,请确定后重新输入!任意键退出!\n");
getchar();
exit(1);
}
int*p=&(L.elem[i-1]);//p为删除位置
int*q=L.elem+L.length-1;//q为表尾位置
for(++p;p<=q;++p)
{
*(p-1)=*p;//被删除元素之后的元素左移
}
--L.length;//表长减1
}

//************数值定位函数,返回元素e在L中的位置,若没有,返回0***************
intLocateElem(SqListL,inte)
{
//在顺序线性表中查找第一个与元素e相同位序
//若找到,则返回其在L中的位序,否则返回0
inti=1;//i的初始值为第一个元素的位序
int*p=L.elem;//p的初始值为第一个元素的存储位置
while(i<=L.length&&e!=*p)
{
++i;
++p;
}
if(i<=L.length)
returni;
else
return0;
}

//**********************取出指定位序的线性表中的数据元素***********************
intGetElem(SqListL,inti)
{
//将线性表L中的第i个元素返回给e
if(i<1||i>L.length)
{
printf("该数据元素不存在,请仔细确认!任意键退出\n");
getchar();
exit(1);
}
//int*q=&L.elem[i-1];
//inte=*q;
inte=L.elem[i-1];
//因为elem是一个数组指针,当只用elem时,代表首地址
//,若具体指定某一个数elem[i],则代表第i+1个元素,故下面和上面的注释方法都可行
//int*p=L.elem;
//inte=*(p+i-1);
returne;

}

//****************************线性顺序表的合并********************************
/**
该方法的线性复杂度为O(ListLength(LA)xListLength(LB))
该方法得到的线性表是无序的,数据直接插在一个线性表的最后
是将所有在线性表Lb中但不在La中的数据元素插入到La中,无重复项
*/
voidListUnoin(SqList&La,SqListLb)
{
//将所有在线性表Lb中但不在La中的数据元素插入到La中
intla_len=La.length;
intlb_len=Lb.length;
inte;
for(inti=1;i<=lb_len;++i)
{
e=GetElem(Lb,i);//取Lb中第i个元素赋值给e
//printf("%d\n",e);
if(!LocateElem(La,e))
{
ListInsert(La,++la_len,e);//将数据插在La的末尾
}
}
}

//**************************有序线性顺序表的合并*******************************
/**
通过增加一个线性表,使得时间复杂度由O(ListLength(LA)xListLength(LB))变成
了O(ListLength(LA)+ListLength(LB))
不过使用这种方法需要有个前提:La和Lb已经排序
得到的结果Lc也是排好序的线性表
*/
voidMergeList(SqListLa,SqListLb,SqList&Lc)
{
//本例中以非递减排序为例
int*pa=La.elem;
int*pb=Lb.elem;
Lc.length=La.length+Lb.length;
Lc.listsize=Lc.length;
Lc.elem=(int*)malloc(Lc.listsize*sizeof(int));
if(!Lc.elem)
{
printf("存储分配失败,任意键退出!\n");
getchar();
exit(1);
}
int*pc=Lc.elem;
int*pa_last=La.elem+La.length-1;
int*pb_last=Lb.elem+Lb.length-1;
while(pa<=pa_last&&pb<=pb_last)//归并操作
{
if(*pa<=*pb)
*pc++=*pa++;
else
*pc++=*pb++;
}
while(pa<=pa_last)
*pc++=*pa++;//插入La的剩余元素
while(pb<=pb_last)
*pc++=*pb++;//插入Lb的剩余元素
}

intmain()
{
//首先输入10个数据,构造一个线性表,测试建表,输出,插入,删除功能是否正确
SqListLa,Lb,Lc;
InitList(La);
InitList(Lb);
InitList(Lc);
intcount,value,location;
printf("请输入建立顺序表La的元素个数:");
scanf("%d",&count);
printf("请依次输入%d个数据:",count);
for(inti=0;i<count;++i)
{
//将输入的数据插入到顺序表La中
scanf("%d",&value);
ListInsert(La,i+1,value);
}
//输出线性表的数据
printf("该顺序线性表的数据元素为:");
PrintList(La);

//测试插入数据是否可行
printf("\n请输入插入位置和插入值:");
scanf("%d%d",&location,&value);
ListInsert(La,location,value);
printf("插入之后的数据元素为:");
PrintList(La);

//测试删除数据情况
printf("\n请输入删除位置:");
scanf("%d",&location);
ListDelete(La,location);
printf("数据删除之后的元素为:");
PrintList(La);

//测试顺序表的合并,需要两个有序的顺序表
printf("\n请输入建立顺序表Lb的元素个数:");
scanf("%d",&count);
printf("请依次输入%d个数据:",count);
for(inti=0;i<count;++i)
{
//将输入的数据插入到顺序表La中
scanf("%d",&value);
ListInsert(Lb,i+1,value);
}
MergeList(La,Lb,Lc);
printf("将La和Lb合并之后的Lc数据元素为:");
PrintList(Lc);

printf("\n采用时间复杂度更高的合并方式为:");
ListUnoin(La,Lb);
PrintList(La);

return0;
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: