一、基本概念
概念:零个或多个数据元素的有限序列
元素之间是有顺序了。如果存在多个元素,第一个元素无前驱,最后一个没有后继,其他的元素只有一个前驱和一个后继。
当线性表元素的个数n(n>=0)定义为线性表的长度,当n=0时,为空表。在非空的表中每个元素都有一个确定的位置,如果a1是第一个元素,那么an就是第n个元素。
线性表的常规操作 ADT
typedef struct person {
char name[32];
char sex;
int age;
int score;
}DATATYPE;
//typedef int Datatype;
typedef struct list {
DATATYPE *head;//数组名
int tlen;//数组有多大
int clen;//当前存储了几个元素
}SeqList;
例:
1.SeqList *CreateSeqList(int len);
2.int DestroySeqList(SeqList *list);
3.int ShowSeqList(SeqList *list);
4.int InsertTailSeqList(SeqList *list, DATATYPE data);
5.int IsFullSeqList(SeqList *list);
6.int IsEmptySeqList(SeqList *list);
7.int InsertPosSeqList(SeqList *list, DATATYPE data, int pos);
8.int FindSeqList(SeqList *list, char *name);
9.int ModifySeqList(SeqList *list, char *old, DATATYPE new);
10.int DeleteSeqList(SeqList *list, char *name);
11.int ClearSeqList(SeqList *list);
内存泄露检测工具
sudo apt-get install valgrind
valgrind ./all
1. CreateSeqList 创建表
SeqList *CreateSeqList(int size) {if(size<=0){fprintf(stderr,"size is error,range >1");return NULL;}SeqList* sl = ( SeqList*)malloc(sizeof(SeqList));if(NULL == sl){perror("CreateSeqList malloc");exit(1);}sl->head = (DATATYPE*)malloc(sizeof(DATATYPE)*size);if(NULL == sl->head){perror("CreateSeqList malloc");exit(1);}sl->tlen = size;sl->clen = 0;return sl; }
2. DestroySeqList 销毁表
int DestroySeqList(SeqList *sl) {if(NULL == sl){fprintf(stderr,"SeqList point not NULL");return 1;}if(sl->head)free(sl->head);free(sl);return 0; }
3. ShowSeqList 遍历表,打印内容
int ShowSeqList(SeqList *list) {if(NULL == list){fprintf(stderr,"list error,list is null\n");return -1;}int i = 0 ;int len = GetSizeSeqList(list);for(i=0;i<len;i++){printf("name:%s sex:%c age:%d score:%d\n",list->head[i].name,list->head[i].sex,list->head[i].age,list->head[i].score);}return 0; }
4. InsertTailSeqList 尾插
int InsertTailSeqList(SeqList *list, DATATYPE *data) {if(NULL == list){fprintf(stderr,"InsertTailSeqList error,list is null\n");return -1;}if(IsFullSeqList(list)){fprintf(stderr,"InsertTailSeqList error ,seqlist is full\n");return 1;}memcpy(&list->head[list->clen] , data,sizeof(DATATYPE));list->clen++;return 0; }
5. IsFullSeqList 表满判断
int IsFullSeqList(SeqList *list) {if(NULL == list){fprintf(stderr,"IsFullSeqList error,list is null\n");return -1;}return list->clen == list->tlen; }
6. IsEmptySeqList 表空判断
int IsEmptySeqList(SeqList *list) {return 0==list->clen; }
7. InsertPosSeqList 任意位置插入
int InsertPosSeqList(SeqList *list, DATATYPE *data, int pos) {if(NULL == list){fprintf(stderr,"list is null\n");return 1;}if(IsFullSeqList(list)){fprintf(stderr,"list is full\n");return 1;}if(pos<0 ||pos>GetSizeSeqList(list)){fprintf(stderr,"pos is error\n");return 1;}int i = 0 ;for(i =GetSizeSeqList(list); i>=pos ; i-- ){memcpy(&list->head[i],&list->head[i-1],sizeof(DATATYPE));}memcpy(&list->head[pos],data,sizeof(DATATYPE));list->clen++;return 0; }
8. FindSeqList 查找表内某个内容,返回其下标
int FindSeqList(SeqList *list, char *name) {if(NULL == list){fprintf(stderr,"FindSeqList error,list is null\n");return 1;}if(IsEmptySeqList(list)){fprintf(stderr,"FindSeqList error,seqlist is empty\n");return -1;}int len = GetSizeSeqList(list);int i = 0 ;for(i=0;i<len;i++){if(0==strcmp(list->head[i].name,name)){return i;}}return -1; }
9. ModifySeqList 修改表内某个内容
int ModifySeqList(SeqList *list, char *old, DATATYPE *newdata) {if(NULL == list){fprintf(stderr,"ModifySeqList error,list is null\n");return 1;}int ret = FindSeqList(list,old);if(-1 == ret){fprintf(stderr,"modify error,can't find\n");return 1;}DATATYPE* tmp = GetSeqListItem(list,ret);memcpy(tmp,newdata,sizeof(DATATYPE));return 0; }
10. DeleteSeqList 删除表的内容
int DeleteSeqList(SeqList *list, char *name) {if(NULL == list){fprintf(stderr,"DeleteSeqList error,list is null\n");return 1;}int ret = FindSeqList(list,name);if(-1 == ret){return 1;}else{int i = 0 ;for(i =ret; i <GetSizeSeqList(list)-1 ; i++){memcpy(&list->head[i] ,&list->head[i+1],sizeof(DATATYPE));}}list->clen--;return 0 ; }
11. ClearSeqList 把表清空
int CleanSeqList(SeqList *list) {if(NULL == list){fprintf(stderr,"CleanSeqList error,list is null\n");return 1;}list->clen = 0 ;return 0; }
main.c
#include <stdio.h> #include "seqlist.h" int main() {SeqList* sl = CreateSeqList(10);DATATYPE data[5]={{"zhangsan",'m',20,70},{"lisi",'f',21,60},{"wangmazi",'m',25,80},{"liubei",'f',30,85},{"caocao",'f',40,90},};InsertTailSeqList(sl,&data[0]);InsertTailSeqList(sl,&data[1]);InsertTailSeqList(sl,&data[2]);printf("----------------show------------------\n");ShowSeqList(sl);printf("----------------find------------------\n");char find_name[50]="lisi";int ret = FindSeqList(sl,find_name);if(-1 == ret){printf("can't find person ,%s\n",find_name);}else{DATATYPE* tmp = GetSeqListItem(sl,ret) ;printf("name:%s score:%d\n",tmp->name,tmp->score);}printf("----------------pos------------------\n");InsertPosSeqList(sl,&data[3],3);ShowSeqList(sl);printf("----------------modify------------------\n");ModifySeqList(sl,"li1si",&data[4]);ShowSeqList(sl);printf("----------------delete------------------\n");DeleteSeqList(sl,"zhangsan");ShowSeqList(sl);DestroySeqList(sl);printf("Hello World!\n");return 0; }
二、线性表顺序存储的优点、缺点
优点
1.无需为表中的逻辑关系增加额外的存储空间
2.可以快速随机访问元素,时间复杂度-->O(1),效率高
缺点
1.插入,删除元素需要移动元素,时间复杂度-->O(n),效率较低
2.无法动态存储