1.什么是线性表
具有相同性质的数据元素的有限序列。线性表是一种广泛使用的数据结构,常见的线性表:顺序表,链表,队列,字符串
线性表在逻辑是线性的。
顺序表是数据结构中最为举出最为重要的一环,在此基础上通过修改我们得出链表等结构。每一种数据结构都有自己的优点,今天介绍一下顺序表。
2.顺序表
顺序表相对于比较简单,是一种存放一组连续地址数据的线性表 ,这种表示也称顺序储存结构。其特点是。逻辑上相邻的元素,其物理位置也是相邻的。
3.顺序表的实现
这里我们用动态数实现顺序表,实现一个简单的存放数字的顺序表。
1. 结构体实现
在结构体中,我们主要是成员加成员个数两部分组成,成员可以是结构体指针,数组,各种类型的数据,其次便是成员个数。而对于静态表的实现:
//静态的 struct Sqlist { Datatype a[N];//成员 int size;//成员个数 };
缺点:空间太小不够用,空间太大浪费,不推荐。
我们这里使用动态的数组,即指针来实现:
//动态的 typedef struct Sqlist { Datatype* a;//成员 int size;//有效成员个数 int space;//空间大小 }SL;
我们可以在此基础上空间不够用可以增容,并且实现接口函数如增加数据更为简单。
实现该顺序表操作的一些接口函数:
//函数接口 void SLinit(SL *p);//初始化顺序表 void Destory(SL* p);//销毁顺序表 void SLpushback(SL* p, Datatype x);//尾插 void SLpopback(SL* p, Datatype x);//尾删 void SLpushfront(SL* p, Datatype x);//头插 void SLpopfront(SL* p, Datatype x);//头删 void SLinsert(SL* p,int pos,Datatype x);//给定下标位置插入
初始化顺序表
我们这里初始化时,顺序表里就可以存放四个成员的空间:
void SLinit(SL *p) { p->a = (Datatype*)malloc(sizeof(Datatype)*4);//初始开辟四个成员空间 if (p == NULL) { perror("malooc fail"); return; } p->space = 4; p->size = 0; }
初始化空间根据malloc所扩容的大小决定。
销毁顺序表
void Destory(SL* p) { printf("该表已被删除\n"); free(p); p= NULL; }
对应初始化表,我们不用了就要释放空间,指针置空表示删除表。
检测表容量
因为在实现增删查改,我们需要判断表里的容量是否满成员,于是构造一个检测容量的函数。
void SLchekspace(SL* p) { if (p->size == p->space) { Datatype* tmp = (Datatype*)realloc(p->a,sizeof(Datatype) * 4); if (tmp == NULL) { perror("realloc fail"); return; } p->space = p->space + 4; p->a = tmp; printf("扩容四个元素,现在space大小:%d\n", p->space); } }
头插
void SLpushfront(SL* p, Datatype x) { SLchekspace(p); for(int i=0;i<p->size;i++) { p->a[i + 1] = p->a[i]; } p->a[0] = x; p->size++; printf("插入完毕!\n"); }//头插
头部插入元素,我们只需要成员后移一位,在给头部赋值所插元素。
头删
void SLpopfront(SL* p) { assert(p->size > 0);//判断是否为空成员 for (int i = 0; i < p->size; i++) { p->a[i] = p->a[i + 1]; } p->size--; }//头删
前移一位即可,size--。
尾插
void SLpushback(SL* p, Datatype x) { SLchekspace(p); p->a[p->size] = x; p->size++; }//尾插
尾删
void SLpopback(SL* p) { assert(p->size>0);//判断是否为空成员 p->size--;//直接减size,就无法访问到最后一个数据 }//尾删
给定下标位置插入
void SLinsert(SL* p, int pos, Datatype x) { SLchekspace(p); assert(pos < p->size); p->size++; int n = p->size - 1 - pos; for (int i = 0; i <n; i++) { p->a[pos + i + 1] = p->a[pos + i]; } p->a[pos] = x; }//给下标位置插入
从该位置后移一位。
给定下标位置删除
void SLdelete(SL* p, int pos) { assert(pos < p->size); int n = p->size - 1 - pos; for (int i = 0; i < n; i++) { p->a[pos + i ] = p->a[pos + i+1]; } p->size--; }//给下标位置删除
注意:加标访问时,是在原有数据之下操作的。
整个顺序表实现的结果:
简单的顺序表 - 代码片段 - Gitee.com整个实现功能。