潍坊市论坛

首页 » 分类 » 问答 » 数据结构C语言版线性表的顺序表示
TUhjnbcbe - 2021/8/6 23:03:00
本文介绍一下线性表的顺序存储,以及相关的算法实现,主要是记录并且梳理一下自己实现的算法。本文的参考书目是严蔚敏的《数据结构(C语言版)》。注意这本书在算法实现中用了C++中的引用,而没有用C语言中的指针,所以文件命名后缀为.cpp。先简单介绍一下顺序表。线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素。以元素在计算机内“物理位置相邻”来表示线性表中数据元素之间的逻辑关系。只要确定了存储线性表的起始位置,线性表中任一数据元素都可随机存取,所以线性表的顺序存储结构是一种随机存取的存储结构。线性表的顺序存储结构如下图所示:下面介绍利用C语言实现顺序表的算法,只是简单实现了一些常见的算法,比如:插入,删除

//函数结果状态代码#defineTRUE1#defineFALSE0#defineOK1#defineERROR0#defineINFEASIBLE-1#defineOVERFLOW-2//Status是函数的类型,其值是函数结果状态代码typedefintStatus;由于线性表的长度可变,所以利用动态分配的一维数组来存储数据元素:

typedefintElemType;//线性表元素类型//-----线性表的动态分配顺序存储结构-----#defineLIST_INIT_SIZE10//线性表存储空间的初始分配量#defineLISTINCREMENT10//线性表存储空间的分配增量typedefstruct{ElemType*elem;//存储空间地址intlength;//当前长度intlistsize;//当前分配的存储容量(以sizeof(ElemType))为单位}SqList;顺序表的初始化:

StatusInitList_Sq(SqListL){//构造一个空的顺序表LL.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));if(!L.elem)//判断存储分配是否成功exit(OVERFLOW);L.length=0;//空表长度为0L.listsize=LIST_INIT_SIZE;//初始的存储容量returnOK;}顺序表的长度:

intListLength_Sq(SqListL){returnL.length;}顺序表元素的获取:

intGetElem_Sq(SqListL,inti,ElemTypee){e=L.elem[i-1];returne;}新建一个顺序表:

StatusListCreate_Sq(SqListL,intn){//参数n为要输入的元素的个数if(n=L.listsize){//当存储空间已满时,增加分配空间ElemType*newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));if(!newbase)//判断存储分配是否成功exit(OVERFLOW);L.elem=newbase;L.listsize+=LISTINCREMENT;}printf("pleaseenternumber:");for(inti=0;in;i++){//数据元素的输入scanf("%d",L.elem);L.length++;}returnOK;}顺序表插入新的元素:

StatusListInsert_Sq(SqListL,inti,ElemTypee){//在顺序表L中第i个位置之前插入新的元素e//i的合法值为1~ListLength_Sq(L)+1if(i1

iL.length+1)//i的值不合法returnERROR;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;//增加存储容量}int*q=(L.elem[i-1]);//q为插入位置for(int*p=(L.elem[L.length-1]);p=q;--p)*(p+1)=*p;//插入位置及之后的元素后移*q=e;L.length++;//表长增加1returnOK;}线性表的元素删除:

StatusListDelete_Sq(SqListL,inti,ElemTypee){//在顺序表L中删除第i个元素,并用e返回其值//i的合法值为1~ListLength_Sq(L)if(i1

iL.length)//i的值不合法returnERROR;ElemType*p=(L.elem[i-1]);//p为被删除的元素e=*p;ElemType*q=L.elem+L.length-1;//q为表尾元素的位置for(++p;p=q;++p)//被删除元素之后的元素左移*(p-1)=*p;L.length--;//表长减1returnOK;}打印顺序表:

voidListPrint_Sq(SqListL){ElemType*p=L.elem;//p指向数组首位ElemType*p_last=L.elem+L.length-1;//p_last指向数组最后一位while(p=p_last){printf("%d",*p);//输出元素p++;}printf("\n");}顺序表的合并,注意在此算法中要合并的两个顺序表的元素按值非递减排列,代码如下:

voidMergeList_Sq(SqListLa,SqListLb,SqListLc){//已知顺序线性表La和Lb的元素按值非递减排列//归并La和Lb得到新的顺序线性表Lc,Lc的元素也按照值非递减排列ElemType*pa=La.elem;ElemType*pb=Lb.elem;Lc.length=La.length+Lb.length;Lc.listsize=Lc.length;Lc.elem=(ElemType*)malloc(Lc.listsize*sizeof(ElemType));if(!Lc.elem)//地址分配失败exit(OVERFLOW);ElemType*pc=Lc.elem;ElemType*pa_last=La.elem+La.length-1;ElemType*pb_last=Lb.elem+Lb.length-1;while(pa=pa_lastpb=pb_last){//归并if(*pa=*pb)*pc++=*pa++;else*pc++=*pb++;}while(pa=pa_last)//插入La剩余的元素*pc++=*pa++;while(pb=pb_last)//插入Lb剩余的元素*pc++=*pb++;}最后测试算法:

intmain(void){SqListL;ElemTypee1,e2;InitList_Sq(L);ListCreate_Sq(L,12);//创建长度为12的顺序表ListPrint_Sq(L);ListInsert_Sq(L,3,33);//在顺序表第3个位置之前插入元素33ListPrint_Sq(L);ListInsert_Sq(L,14,66);//在顺序表第14位置(表尾)之前插入元素66ListPrint_Sq(L);ListDelete_Sq(L,4,e1);//删除顺序表的第4个元素,返回值赋给e1ListPrint_Sq(L);printf("e1=%d\n",e1);ListDelete_Sq(L,13,e2);//删除顺序表的第13个元素(表尾元素),返回值赋给e1ListPrint_Sq(L);printf("e2=%d\n",e2);/*---测试MergeList_Sq函数*/SqList(La);SqList(Lb);SqList(Lc);InitList_Sq(La);InitList_Sq(Lb);InitList_Sq(Lc);printf("------MergeList_Sq-----\n");ListCreate_Sq(La,5);//创建长度为5的顺序表Laprintf("La:");ListPrint_Sq(La);ListCreate_Sq(Lb,5);//创建长度为5的顺序表Lbprintf("Lb:");ListPrint_Sq(Lb);MergeList_Sq(La,Lb,Lc);//合并La和Lb为Lcprintf("Lc:");ListPrint_Sq(Lc);return0;}算法测试结果如下:预览时标签不可点收录于话题#个上一篇下一篇

1
查看完整版本: 数据结构C语言版线性表的顺序表示