文字描述:

  用一组地址连续的存储单元依次存储线性表的数据元素,只要确定了存储线性表的起始位置,线性表中任一数据元素都可随机存取,所以线性表的顺序存储结构是一种随机存取的存储结构。

  即是,线性表的顺序存储结构的特定是逻辑关系上相邻的两个元素在物理位置上也相邻,因此可以随机存取表中任一元素,它的存储位置可用一个简单、直观的公式来表示。但是这也导致了它的一个弱点,在作插入或删除操作时,需移动大量元素。

示意图

算法分析

  在顺序存储结构的线性表中某个位置上插入或删除一个数据元素,其时间主要耗费在移动元素上,而移动的元素个数取决于插入或删除的位置。故其插入和删除的时间复杂度为n。

  在顺序存储结构的线性表中求“表长”和“取第i个数据元素”的时间复杂度为1。

  在顺序存储结构的线性表中,union算法(将所有在线性表Lb但不在线性表La中的数据元素插入到La,即La=La U Lb), 其时间复杂度为La.length X Lb.length; 但是如果La,Lb是有序的,另外新建Lc存放结果,其时间复杂度将变为MAX(La.length+Lb.length).

代码实现

 //
// Created by lady on 19-1-26.
// /*
现性表的顺序表示和实现
现性表的顺序表示:用一组地址连续的存储单元依次存储线性表的数据元素。
*/
#include <stdio.h>
#include <stdlib.h> //-------------线性表的动态分配顺序存储结构------------------
#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量
#define LIST_INCREMENT 10 //线性表存储空间的分配增量
typedef int ElemType;
typedef struct{
ElemType *elem; //存储空间基址
int length; //当前长度
int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位)
}SqList; /*构造一个空的线性表*/
static int InitList_Sq(SqList *L)
{
if(L==NULL){
return -;
}
if((L->elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType))) == NULL){
//存储分配失败
return -;
}
//空表长度为0
L->length = ;
//初始存储容量
L->listsize = LIST_INIT_SIZE;
return ;
} /*在L中第i个位置之前插入新的数据元素e,L的长度增1*/
static int ListInsert_Sq(SqList *L, int i, ElemType e)
{
//i的合法值为1 <= i <= ListLength_Sq(L)+1
if((i<) || (i>L->length+))
return -;
if(L->length >= L->listsize){
//当前存储空间已满,增加分配
ElemType *newbase = NULL;
if((newbase=(ElemType*)realloc(L->elem, (L->listsize+LIST_INCREMENT)*sizeof(ElemType))) == NULL){
//存储分配失败
return -;
}
//新的基址
L->elem = newbase;
//增加存储容量
L->listsize += LIST_INCREMENT;
}
//q为插入位置
ElemType *q = (L->elem+i-);
ElemType *p;
for(p=(L->elem+L->length-); p>=q; --p){
//插入位置及之后的元素右移
*(p+) = *p;
}
//插入e
*q = e;
//表长增1
L->length += ;
return ;
} /*删除L中的第i个数据元素,并用e返回其值, L的长度减1*/
static int ListDelete_Sq(SqList *L, int i, ElemType *e)
{
//i的合法值为1 <= i <= ListLength_Sq(L)
if((i<) || (i>L->length)){
return -;
}
ElemType *p;
ElemType *q;
//p为被删除元素的位置
p = L->elem+i-;
//被删除元素的值赋给e
*e = *p;
//表尾元素的位置
q = L->elem+L->length-;
for(++p;p<=q;++p){
//被删除元素之后的元素坐移
*(p-) = *p;
}
//表长减1
L->length -= ;
return ;
} /*依次对L的每个数据元素调用函数fun。一旦fun失败,则操作失败*/
static int ListTraverse_Sq(SqList L, int (*fun)(ElemType,int), char info[])
{
printf("顺序存储的线性表%s", info);
int i = ;
for(i=; i<L.length; i++)
{
if(fun(L.elem[i],i+) < ){
printf("Err:when traverse(e,%d) wrong!\n",i);
return -;
}
}
printf("\n");
return ;
} /*
* 在顺序表L中查找第1个值与e满足fun的元素的位序
* 若找到, 则返回其在L中的位置, 否则返回0
*/
static int LocateElem_Sq(SqList L, ElemType e, int (*fun)(ElemType,ElemType))
{
//i的初值为第一个元素的位置
int i = ;
ElemType *p;
//p的初值为第一个元素的存储位置
p = L.elem;
while(i<=L.length && (fun(*p++,e)))
++i;
if(i<=L.length)
return i;
return ;
} /*销毁线性表L*/
static int DestroyList_Sq(SqList *L)
{
if(L == NULL)
return -;
if(L->elem){
free(L->elem);
L->elem = NULL;
}
L->length = ;
L->listsize = ;
return ;
} /*
* 已知顺序线性表La和Lb的元素按照非递减排列
* 归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排列
* 时间复杂度为MAX(La.length, Lb.length)
*/
static int MergeList_Sq(SqList La, SqList Lb, SqList *Lc)
{
if(Lc == NULL){
return -;
} ElemType *pa = La.elem, *pa_last;
ElemType *pb = Lb.elem, *pb_last; Lc->length = La.length + Lb.length;
Lc->listsize = La.length + Lb.length; if((Lc->elem = (ElemType*)malloc(Lc->listsize * sizeof(ElemType))) == NULL){
//存储分配失败
Lc->length = ;
Lc->listsize = ;
return -;
}
ElemType *pc = Lc->elem; pa_last = La.elem+La.length-;
pb_last = Lb.elem+Lb.length-;
while((pa<=pa_last) && (pb<=pb_last)){
//归并
if(*pa <= *pb){
*pc++ = *pa++;
}else{
*pc++ = *pb++;
}
}
while(pa<=pa_last){
//插入La的剩余部分
*pc++ = *pa++;
}
while(pb<=pb_last){
//插入Lb的剩余部分
*pc++ = *pb++;
}
return ;
} //打印位置loc和其数据元素e
static int printE(ElemType e, int loc)
{
printf("%3d=%-3d", loc, e);
return ;
} //比较元素e1和e2是否相等, 相等返回0,否则返回-1
static int equal(ElemType e1, ElemType e2)
{
if(e1==e2){
return ;
}else{
return -;
}
} int main(int argc, char *argv[])
{
SqList L;
if(InitList_Sq((&L)) < ){
printf("Err:init sqList wrong!\n");
goto End;
} ElemType e;
int location;
int data; //以插入法构造一个线性表·[12,13,21,24,28,30,42,77]
ListInsert_Sq(&L, , );
ListInsert_Sq(&L, , );
ListInsert_Sq(&L, , );
ListInsert_Sq(&L, , );
ListInsert_Sq(&L, , );
ListInsert_Sq(&L, , );
ListInsert_Sq(&L, , );
ListInsert_Sq(&L, , );
ListTraverse_Sq(L, printE, "L:");
printf("\n"); //insert a data and print
printf("insert a data and print, please input (locatioon, data):");
scanf("%d,%d", &location, &data);
ListInsert_Sq(&L, location, data);
ListTraverse_Sq(L, printE, "L:");
printf("\n"); //delete a data and print
printf("delete a data and print, please input (location):");
scanf("%d", &location);
ListDelete_Sq(&L, location, &e);
ListTraverse_Sq(L, printE, "L:");
printf("\n"); //locate a data and print
printf("locata a data and print, please input (data):");
scanf("%d", &data);
location = LocateElem_Sq(L, data, equal);
printf("the location of the first data who equals to %d is %d!\n\n", data, location); printf("Merge LA and LB to LC!\n");
SqList La, Lb, Lc;
if(InitList_Sq(&La) || InitList_Sq(&Lb)){
printf("Err:init sqList wrong!\n");
goto End;
}
//构造一个值非递减的线性表:LA [3,5,8,11]
ListInsert_Sq(&La, , );
ListInsert_Sq(&La, , );
ListInsert_Sq(&La, , );
ListInsert_Sq(&La, , );
ListTraverse_Sq(La, printE, "LA"); //构造一个值非递减的线性表:LB [2,6,8,9,11,15,20]
ListInsert_Sq(&Lb, , );
ListInsert_Sq(&Lb, , );
ListInsert_Sq(&Lb, , );
ListInsert_Sq(&Lb, , );
ListInsert_Sq(&Lb, , );
ListInsert_Sq(&Lb, , );
ListInsert_Sq(&Lb, , );
ListTraverse_Sq(Lb, printE, "LB"); //将线性表La和Lb按照非递减形式归并成线性表Lc
if(MergeList_Sq(La, Lb, &Lc))
{
printf("Err:when merge(La,Lb) wrong!\n");
goto End;
}
ListTraverse_Sq(Lc, printE, "LC"); End:
DestroyList_Sq(&L);
DestroyList_Sq(&La);
DestroyList_Sq(&Lb);
DestroyList_Sq(&Lc);
return ;
}

顺序存储的线性表(动态表示)

代码运行

/home/lady/CLionProjects/untitled/cmake-build-debug/untitled
顺序存储的线性表L: 1=12 2=13 3=21 4=24 5=28 6=30 7=42 8=77 insert a data and print, please input (locatioon, data):5,25
顺序存储的线性表L: 1=12 2=13 3=21 4=24 5=25 6=28 7=30 8=42 9=77 delete a data and print, please input (location):5
顺序存储的线性表L: 1=12 2=13 3=21 4=24 5=28 6=30 7=42 8=77 locata a data and print, please input (data):42
the location of the first data who equals to 42 is 7! Merge LA and LB to LC!
顺序存储的线性表LA 1=3 2=5 3=8 4=11
顺序存储的线性表LB 1=2 2=6 3=8 4=9 5=11 6=15 7=20
顺序存储的线性表LC 1=2 2=3 3=5 4=6 5=8 6=8 7=9 8=11 9=11 10=15 11=20 Process finished with exit code 0

最新文章

  1. 逗号分割符--字段中含逗号等情况的解析方法Java实现
  2. TAP/TUN(二)
  3. 第六篇:在SOUI中用九宫格拉伸方式显示一个图片资源
  4. 用CSS定义每段首行缩进2个字符 转
  5. (转)c#.net常用字符串函数
  6. GLSL实现Ambient Occlusion 【转】
  7. 阿里云Ubuntu服务器安装java环境
  8. bzoj 1070 [SCOI2007]修车(最小费用最大流)
  9. C\C++代码优化的27个建议
  10. php创建读取 word.doc文档
  11. 用批处理编译*.sln工程
  12. 从SHAttered事件谈安全
  13. 第 8 章 IO库
  14. [HNOI 2013]数列
  15. JS JavaScript模块化(ES Module/CommonJS/AMD/CMD)
  16. mysql主从服务搭建
  17. Ubuntu16.04配置Tomcat的80端口访问
  18. 2017-9-8-Linux下VNC server开启&amp;图形界面显示
  19. canvas-tangram.html
  20. 【MongoDB】MongoDb的“not master and slaveok=false”错误及解决方法 mongo连接从库出现问题

热门文章

  1. 初学python之路-day04
  2. javascript事件委托的原理与实现
  3. Bootstrap-datepicker3官方文档中文翻译---概述(原文链接 http://bootstrap-datepicker.readthedocs.io/en/latest/index.html)
  4. CentOS7.X首次安装docker无法启动的问题解决
  5. STM32串口空闲中断
  6. Jmeter性能测试之关联(三)
  7. MySQL和B树的那些事
  8. MVC4 发布到II7或者IIS7.5遇到NO Find问题
  9. WIN10在安装mysql时,出现“The security settings could not be applied to the database because the connection has failed with the following error. Error Nr. 1045
  10. PID实战-STM32电机PWM力矩调节系统