数据结构线性表的动态分配顺序存储结构算法c语言具体实现和算法时间复杂度分析
#include<stdio.h>
#include<stdlib.h>
//线性表的动态分配顺序存储结构
#define LIST_INIT_SIZE 100//线性表存储空间的初始分配量
#define LISTINCREMENT 10//线性表存储空间的分配增量
//函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;//Status是函数的类型,其值是函数结果状态代码
typedef int ElemType;
//线性表的动态分配顺序存储结构
typedef struct{
ElemType *elem;//存储空间基址
int length;//当前长度
int listsize;//当前分配的存储容量的(以sizeof(ElemType)为单位)
}SqlList;
//构造一个空的线性表L
//O(1)
Status InitList_Sq(SqlList &L)
{
//构造一个空的线性表
L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!L.elem)
{
printf("线性表L构造失败!\n");
exit(OVERFLOW);//存储分配失败
}
L.length=0;//空表的长度为0
L.listsize=LIST_INIT_SIZE;//初始的存储容量
printf("线性表L构造成功!\n");
return OK;
}//InitList_Sq
//销毁线性表L
//O(1)
Status DestroyList_Sq(SqlList &L)
{
if(L.elem!=NULL)
{
free(L.elem);
L.elem=NULL;
L.length=0;
L.listsize=0;
printf("销毁线性表L成功\n");
return OK;
}else
{
printf("线性表L不存在\n");
}
return ERROR;
}//DestroyList_Sq
//将L重置为空表
//O(1)
Status ClearList_Sq(SqlList &L)
{
if(L.elem!=NULL)
{
L.length=0;
printf("已将线性表重置为空表!\n");
return OK;
}else
printf("线性表重置为空表失败!\n");
return ERROR;
}//ClearList_Sq
//若L为空表,则返回TRUE,否则返回FALSE
//O(1)
Status ListEmpty_Sq(SqlList L)
{
if(L.elem!=NULL&&L.length==0)
{
printf("线性表L为空表\n");
return TRUE;
}else if(L.elem!=NULL)
{
printf("线性表L不为空表\n");
return FALSE;
}else{
printf("线性表L不存在\n");
return FALSE;
}
}//ListEmpty_Sq
//返回L中数据元素的个数
//o(1)
Status ListLength_Sq(SqlList L)
{
if(L.elem!=NULL)
{
printf("线性表L的长度为%d\n",L.length);
return L.length;
}else
printf("线性表L不存在");
return -1;
}//ListLength_Sq
//用e返回L中第i个元素的值
//O(1)
void GetElem_Sq(SqlList L,int i,ElemType &e)
{
if(L.elem!=NULL)
{
if(i<1||i>L.length)
printf("访问位置非法");
else
{
e=L.elem[i-1];
}
}else
printf("线性表L不存在");
}//GetElem_Sq
//返回L中第一个与e满足关系compare()的元素的位序。若这样的数据元素不存在,则返回值为0
//O(n)
Status LocateElem_Sq(SqlList L,ElemType e,Status (*compare)(ElemType,ElemType))
{
int i=1;
ElemType *p=L.elem;
if(L.elem!=NULL)
{
while(i<=L.length&&!(*compare)(*p++,e))
{
++i;
}
if(i<=L.length)
{
printf("找到元素e在线性表L的位置为第%d个",i);
return i;
}else
{
printf("线性表L中不存在元素e");
return 0;
}
}else
printf("线性表L不存在");
return 0;
}//LocateElem_Sq
//若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则失败,pre_e无定义
//O(n)
Status PriorElem_Sq(SqlList L,ElemType cur_e,ElemType *pre_e)
{
int i=2;
if(L.elem!=NULL)
{
while(i<=L.length)
{
if(cur_e==L.elem[i-1])
*pre_e=L.elem[i-2];
++i;
return OK;
}
return ERROR;
}else
printf("线性表L不存在");
return ERROR;
}//PriorElem_Sq
//若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,否则操作失败,next_e无定义
//O(n)
Status NextElem_Sq(SqlList L,ElemType cur_e,ElemType *next_e)
{
int i=1;
if(L.elem!=NULL)
{
while(i<=L.length-1)
{
if(cur_e==L.elem[i-1])
*next_e=L.elem[i];
++i;
return OK;
}
return ERROR;
}else
printf("线性表L不存在");
return ERROR;
}//NextElem_Sq
//在L中第i个位置之前插入新的数据元素e,L的长度加1
//一般情况下,在第i(1<=i<=n)个元素之前插入一个元素时,需要将第n至第i(共n-i+1)个元素向后移动一个位置
//假如pi是在第i个元素之前插入一个元素的概率,则在长度为n线性表中插入一个元素时所需移动元素的期望值(平均次数)为E(is)=pi(n-i+1),(i从1到n+1的和式)。
//不失一般性,我们可以假定在线性表的任何位置上插入,即,pi=1/(1+n),则上式可简化为,E(is)=n/2。可见在顺序存储结构的线性表插入一个元素,平均约移动表中一半元素。若表长为n,则这个算法的时间复杂度为O(n)。
Status ListInsert_Sq(SqlList &L,int i,ElemType e)
{
if(L.elem!=NULL)
{
if(i<1||i>L.length+1) return ERROR;
if(L.length>=L.listsize)
{
ElemType *newbase=(ElemType *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
if(!newbase)
{
exit(OVERFLOW);//存储分配失败
}
L.elem=newbase;//新基址
L.listsize+=LISTINCREMENT;//增加存储容量
}
ElemType *q,*p;
q=&L.elem[i-1];
for(p=&L.elem[L.length-1];p>=q;p--) *(p+1)=*p;//插入位置及以后元素后移
*q=e;//插入e
++L.length;//表长增1
return OK;
}else
printf("线性表L不存在");
return ERROR;
}//ListInsert_Sq
//删除L的第i个数据元素,并用e返回其值,L的长度减1
//一般情况下,删除第(1<=i<=n)个元素时需从第i+1至第n个(共n-i)个元素依次向前移动一个位置
//假如qi是在第i个删除第i个元素的概率,则在长度为n的线性表中删除一个元素时所需移动元素的次数的期望(平均次数为)E(dl)=qi(n-i),(i从n的和式)。
//不失一般性,我们可以假定在线性表的任何位置上删除元素都是等概率的,即qi=1/n,则上式可简化为,E(dl)=(n-1)/2。可见在顺序存储结构的线性表删除一个元素,平均约移动表中一半元素。若表长为n,则这个算法的时间复杂度为O(n)。
Status ListDelete_Sq(SqlList &L,int i,ElemType &e)
{
if(L.elem!=NULL)
{
if(i<1||i>L.length) return ERROR;//i的位置不合法
ElemType *p,*q;
p=&L.elem[i-1];//p为被删除元素的位置
e=*p;//被删除的元素赋给e
q=L.elem+L.length-1;//表尾元素的位置
for(++p;p<=q;++p) *(p-1)=*p;//被删除元素之后的元素左移
--L.length;
return OK;
}else
printf("线性表L不存在");
return ERROR;
}//ListDelete_Sq
//依次对L的每个数据元素调用函数visit().一旦visit失败,则操作失败
//O(n)
void ListTraverse_Sq(SqlList L,Status (*visit)(ElemType))
{
if(L.elem!=NULL)
{
if(L.length==0)
{
printf("线性表为空\n");
}else
{
for(int i=1;i<=L.length;i++)
{
if((*visit)(L.elem[i-1]))
{
}
else
{
printf("数据遍历失败");
return;
}
}
printf("线性表为:");
for(int i=1;i<=L.length;i++)
{
printf("%d,",L.elem[i-1]);
}
}
}else
{
printf("线性表L不存在\n");
}
}//ListTraverse_Sq
//L中第i个元素赋值同e的值
//O(1)
Status PutElem_Sq(SqlList L,int i,ElemType &e)
{
if(L.elem!=NULL)
{
if(i<1||i>L.length)
{
printf("赋值在线性表中的位置非法\n");
return ERROR;
}else{
L.elem[i-1]=e;
return OK;
}
}
else
{
printf("线性表L不存在\n");
return ERROR;
}
}//PutElem_Sq
//两个顺序表合并
//O(La.length+Lb.length)
void MergeList_Sq(SqlList La,SqlList Lb,SqlList &Lc)
{
//已知顺序线性表La和Lb的元素按值非递减排列
//归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排列
ElemType *pa=La.elem;
ElemType *pb=Lb.elem;
Lc.listsize=Lc.length=La.length+Lb.length;
ElemType *pc=Lc.elem=(ElemType *)malloc(Lc.listsize*sizeof(ElemType));
if(!Lc.elem) exit(OVERFLOW);//存储分配失败
ElemType *pa_last=La.elem+La.length-1;
ElemType *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的剩余元素
}//MergeList_Sq
int main()
{
SqlList L,La,Lb,Lc;
ElemType i,e;
//初始化线性表
InitList_Sq(L);
InitList_Sq(La);
InitList_Sq(Lb);
for(i=1;i<=LISTINCREMENT;i++)
{
ListInsert_Sq(La,i,i);
ListInsert_Sq(Lb,i,i+1);
}
MergeList_Sq(La,Lb,Lc);
printf("线性表La中的元素为:");
for(i=1;i<=La.length;i++)
{
GetElem_Sq(La,i,e);
printf("%d,",e);
}
printf("\n线性表La中的元素为:");
for(i=1;i<=Lb.length;i++)
{
GetElem_Sq(Lb,i,e);
printf("%d,",e);
}
printf("\n线性表Lc中的元素为:");
for(i=1;i<=Lc.length;i++)
{
GetElem_Sq(Lc,i,e);
printf("%d,",e);
}
DestroyList_Sq(La);
DestroyList_Sq(Lb);
DestroyList_Sq(Lc);
/*for(i=1;i<=LISTINCREMENT;i++)
{
L.elem[i-1]=i;
L.length++;
}*/
//给线性表赋值
/*for(i=1;i<=LISTINCREMENT;i++)
{
ListInsert_Sq(L,i,i);
}*/
/*printf("线性表中的元素为:");
for(i=1;i<=LISTINCREMENT;i++)
{
GetElem_Sq(L,i,e);
printf("%d,",e);
}*/
/*printf("线性表L元素为:");
//直接给线性表赋值,有可能会产生溢出现象,如果下标超出内存分配上届
for(i=1;i<=LISTINCREMENT;i++)
{
printf("%d,",L.elem[i-1]);
}*/
//遍历整个线性表L
//ListTraverse_Sq(L);
//得到线性表长度
ListLength_Sq(L);
//判断线性表是否为空
ListEmpty_Sq(L);
//清空线性表中的数据
ClearList_Sq(L);
//销毁整个线性表
DestroyList_Sq(L);
//清空线性表中的数据
ClearList_Sq(L);
getchar();
getchar();
return 0;
}
数据结构线性表的动态分配顺序存储结构算法c语言具体实现和算法时间复杂度分析的更多相关文章
- 动态分配的顺序线性表的十五种操作—C语言实现
线性表 定义:是最常用的,也是最简单的数据结构,是长度为n个数据元素的有序的序列. 含有大量记录的线性表叫文件 记录:稍微复杂的线性表里,数据元素为若干个数据项组成,这时把一个数据元素叫记录 结构特点 ...
- 线性表之顺序存储结构(C语言动态数组实现)
线性表的定义:N个数据元素的有限序列 线性表从存储结构上分为:顺序存储结构(数组)和 链式存储结构(链表) 顺序存储结构:是用一段连续的内存空间存储表中的数据 L=(a1,a2,a3....an) 链 ...
- [从今天开始修炼数据结构]线性表及其实现以及实现有Itertor的ArrayList和LinkedList
一.线性表 1,什么是线性表 线性表就是零个或多个数据元素的有限序列.线性表中的每个元素只能有零个或一个前驱元素,零个或一个后继元素.在较复杂的线性表中,一个数据元素可以由若干个数据项组成.比如牵手排 ...
- [数据结构-线性表1.2] 链表与 LinkedList<T>(.NET 源码学习)
[数据结构-线性表1.2] 链表与 LinkedList<T> [注:本篇文章源码内容较少,分析度较浅,请酌情选择阅读] 关键词:链表(数据结构) C#中的链表(源码) 可空类 ...
- 2019-02-03 线性表的顺序储存结构C语言实现
#include<cstdio> #define MAXSIZE 20 typedef int Elemtype; //Elemtype类型根据实际情况而定,这里取int typedef ...
- [置顶] ※数据结构※→☆线性表结构(queue)☆============循环队列 顺序存储结构(queue circular sequence)(十)
循环队列 为充分利用向量空间,克服"假溢出"现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量.存储在其中的队列称为循环队列(Circular Queue). ...
- 数据结构4:顺序表(线性表的顺序存储结构)及C语言实现
逻辑结构上呈线性分布的数据元素在实际的物理存储结构中也同样相互之间紧挨着,这种存储结构称为线性表的顺序存储结构. 也就是说,逻辑上具有线性关系的数据按照前后的次序全部存储在一整块连续的内存空间中,之间 ...
- c数据结构 -- 线性表之 顺序存储结构 于 链式存储结构 (单链表)
线性表 定义:线性表是具有相同特性的数据元素的一个有限序列 类型: 1:顺序存储结构 定义:把逻辑上相邻的数据元素存储在物理上相邻的存储单元中的存储结构 算法: #include <stdio. ...
- [置顶] ※数据结构※→☆线性表结构(queue)☆============队列 顺序存储结构(queue sequence)(八)
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表.进行插入操作的端称为队尾,进行删除操作的 ...
随机推荐
- sencha touch list tpl 监听组件插件(2013-9-15)
插件代码 /* *list tpl模版加入按钮监控 *<div class="x-button-normal x-button x-iconalign-center x-layout- ...
- [原]openstack-kilo--issue(三) openstack-nova-issue-systemctl start openstack-nova-compute.service
本博客已经添加"打赏"功能,"打赏"位置位于右边栏红色框中,感谢您赞助的咖啡. execute systemctl start openstack-nova-c ...
- oracle索引优化
零.概述 在这之前,一直都是使用mysql来进行开发或者部署.最近及今后很长一段时间都要使用oracle,今天和同事也遇到一个oracle 慢查询问题.查了很多资料,这里记录备忘.持续更新ing... ...
- ELK系列七:Elasticsearch的集群配置和监控以及在部署ELK中踩的坑
1.基本下载安装 #按照ELK系列一博客安装启动即可,没有大坑,注意一下权限即可 chmod -R 777 ./elasticsearch #此外没有java的,注意安装下JDK,我这次部署的环境是C ...
- stdarg.h头文件源代码分析
谈到C语言中可变参数函数的实现(参见C语言中可变参数函数实现原理),有一个头文件不得不谈,那就是stdarg.h 本文从minix源码中的stdarg.h头文件入手进行分析: #ifndef _STD ...
- 通过Adb 查看当前正在运行的Activity.
extends:http://www.cnblogs.com/tt_mc/p/4269833.html adb shell dumpsys activity activities | sed -En ...
- RabbitMQ安装详解(centos6.8)(转自:http://www.cnblogs.com/zhen-rh/p/6862350.html)
1.下载rabbitmq安装包 2.安装erlang a.安装Erlang Solutions仓库到你的系统(目的在于让你可以使用yum安装到最新版本的erlang, 如果不设置, yum安装的erl ...
- OC开发_整理笔记——友盟分享(社交化组件)
0.友盟的地址 http://dev.umeng.com,进入友盟,在使用友盟之前我们需要注册账号获取key (1 进入我们的产品,添加新应用 (2 输入信息,然后就会获取到key 1.选择社会化分 ...
- App开发如何制作测试数据
OHHTTPStubs 使用第三方请求库模拟返回json数据 https://github.com/AliSoftware/OHHTTPStubs 使用青花瓷maplocal制造假数据 https:/ ...
- cURL 是一个功能强大的PHP库。
使用PHP的cURL库可以简单和有效地去抓网页.你只需要运行一个脚本,然后分析一下你所抓取的网页,然后就可以以程序的方式得到你想要的数据了.无论是你想从从一个链接上取部分数据,或是取一个XML文件并把 ...