线性表:线性表(Linear List)是由n(n≥0)个数据元素(结点)a[0],a[1],a[2]…,a[n-1]组成的有限序列c++
其中:算法
数据元素的个数n定义为表的长度 = "list".length() ("list".length() = 0(表里没有一个元素)时称为空表)数组
将非空的线性表(n>=0)记做:(a[0],a[1],a[2],…,a[n-1])数据结构
数据元素a[i](0≤i≤n-1)只是个抽象符号,其具体含义在不一样状况下能够不一样函数
//线性表的顺序存储结构 typedef struct{ int *elem; //存储空间基址,即线性表的起始位置,elem指向int的指针 int length; //当前长度 int listsize; //当前分配的存储容量 }SqList;
线性表的顺序表示指的是一组地址连续的存储单元依次存储线性表的数据元素。spa
线性表的顺序存储结构是一种随机存储的存储结构。指针
由于内存中的地址空间是线性的,所以,用物理上的相邻实现数据元素之间的逻辑相邻关系是既简单,又天然的。code
因为数组类型也有随机存储的特性,所以一般用数组来描述数据结构中的顺序存储结构。内存
因为线性表的长度可变,且所需最大存储空间随问题不一样而不一样,则在C语言中可用动态分配的一维数组。input
线性表的起始位置=基地址,每一个数据元素占1个存储地址
线性表的顺序表示和实现:
//Sequence List #include<stdio.h> #include<malloc.h> #include<stdlib.h> #define LIST_INIT_SIZE 10 #define LISTINCREMENT 2 #define OVERFLOW -2 #define OK 1 #define ERROR 0 //为内置类型int建立两个别名,新的名字 typedef int Status; typedef int ElemType; //线性表的顺序存储结构 typedef struct{ int *elem; //存储空间基址,即线性表的起始位置 int length; //当前长度 int listsize; //当前分配的存储容量 }SqList; //初始化顺序表 Status InitList_Sq(SqList* L); //顺序表中插入元素 Status ListInsert_Sq(SqList* L,int i,ElemType e); //顺序表的合并 Status MergeList_Sq(SqList La,SqList Lb,SqList* Lc); //顺序表元素的输出 Status ListPrint_Sq(SqList* L); //顺序表元素的删除 //删除第i个位置上的元素,并用e返回其值 Status ListDelete_Sq(SqList* L,int i,ElemType *e); int main() { SqList La,Lb,Lc; int i = 1; ElemType num = 0; //初始化顺序表La InitList_Sq(&La); //初始化顺序表Lb InitList_Sq(&Lb); printf("Please input the number(end by -1):\n"); while(1) { scanf("%d",&num); if(num == -1) break; ListInsert_Sq(&La,i,num); i++; } ListPrint_Sq(&La); i = 1; printf("Please input the number(end by -1):\n"); while(1) { scanf("%d",&num); if(num == -1) break; ListInsert_Sq(&Lb,i,num); i++; } ListPrint_Sq(&Lb); //顺序表合并的算法函数 MergeList_Sq(La,Lb,&Lc); printf("MergeList OK\n"); ListPrint_Sq(&Lc);\ int dl=0; ListDelete_Sq(&Lc,4,&dl); printf("Delete OK %d\n",dl); ListPrint_Sq(&Lc); } Status MergeList_Sq(SqList La,SqList Lb,SqList* Lc) { ElemType *pa=La.elem,*pb=Lb.elem,*pc; ElemType *pa_last,*pb_last; Lc->listsize = Lc->length = La.length+Lb.length; pc= Lc->elem = (ElemType*)malloc(Lc->listsize*sizeof(ElemType));//为pc顺序表分配内存空间 if(!Lc->elem) exit(OVERFLOW); pa_last = La.elem + La.length - 1; 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){ //插入La的剩余元素 *pc++ = *pa++; //====>>*pc=*pa;pc++;pa++;//真的不推荐写成*pc++ = *pa++; } while(pb<=pb_last) //插入Lb的剩余元素 { *pc++ = *pb++; } return OK; } /* 顺序表的初始化操做就是为顺序表分配一个预约义大小的数组空间,并将线性表的当前长度设为0 malloc分配指定的字节,并返回指向这块内存的指针。若是分配失败,则返回一个空指针(NULL) */ Status InitList_Sq(SqList* L) { // L->elem = (ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType)); if(!L->elem) //若是顺序表分配失败 exit(OVERFLOW); L->length = 0;//顺序表的当前长度为零 L->listsize = LIST_INIT_SIZE; return OK; } /* (ElemType*)realloc(L->elem,(L->listsize + LISTINCREMENT)*sizeof(ElemType)); realloc函数的做用:第一参数是指针,指向现有的一块内存区域,第二个参数为新的内存区域的大小 若是从新分配成功则返回指向被分配内存的指针,不然返回空指针NULL 该函数功能:在顺序表L第i个位置插入元素e */ Status ListInsert_Sq(SqList* L,int i,ElemType e) { ElemType *newbase,*p,*q; if(i<1 || i> L->length+1) return ERROR; if(L->length >= L->listsize) { newbase = (ElemType*)realloc(L->elem,(L->listsize + LISTINCREMENT)*sizeof(ElemType)); if(!newbase) exit(OVERFLOW); L->elem = newbase; L->listsize += LISTINCREMENT; } q = &(L->elem[i-1]); //q为元素的插入位置,是一个指针 //&(L->elem[L->length-1])获取线性表中最后一个元素的指针 for(p=&(L->elem[L->length-1]);p>=q;--p) { *(p+1) = *p; //元素的位置右移 } *q = e; //把元素e插入位置q ++L->length; //把当前顺序表的长度加一 return OK; } Status ListPrint_Sq(SqList* L) { int i = 0; ElemType num = 0; for(i=0;i<L->length;i++) { num = L->elem[i]; printf("No.%d\t%d\n",i,num); } return OK; } //在顺序表L中删除第i个元素,并用e返回其值 Status ListDelete_Sq(SqList* L,int i,ElemType *e) { ElemType *p,*q; if(i<0||i>L->length){ return ERROR; } p = &(L->elem[i-1]); //删除元素的位置 *e = *p; //删除元素的值 q = L->elem+L->length-1; //顺序表中最后一个元素的位置 for(++p;p<=q;++p) { *(p-1)=*p; //删除元素以后的元素左移 } --L->length; //顺序表的长度减一 return OK; }
运行结果:
Please input the number(end by -1): 1 2 3 4 -1 No.0 1 No.1 2 No.2 3 No.3 4 Please input the number(end by -1): 5 6 7 8 -1 No.0 5 No.1 6 No.2 7 No.3 8 MergeList OK No.0 1 No.1 2 No.2 3 No.3 4 No.4 5 No.5 6 No.6 7 No.7 8 Delete OK 4 No.0 1 No.1 2 No.2 3 No.3 5 No.4 6 No.5 7 No.6 8 Process returned 1 (0x1) execution time : 11.704 s Press any key to continue.
====END====