本文主要内容:顺序表的增删改查,一代(数组)、二代(malloc)、3代(零元数组)。
顺序表:线性表的顺序结构。1:1
例如一个数组:
a | b | c | d | e |
a、b、c、d、e是数组中的值。
因为在C语言中没有绝对的清空,都是覆盖(如清0),无法确定其中某个值是垃圾还是需要的数据。如果变量不足以自证哪是数据哪是垃圾,则增加一个数据来保全功能性。
第一代
定义结构体:
#define SIZE 20typedef struct list{ int data[SIZE];//存放数据元素 int last;//标记位,标记表中最后一位有效数据的位置(记录数组下标) // -1恰好比较合适表示 空}list_t;//顺序表的类型
初始化:
list_t * creat_list() { //堆区申请空间 list_t * list = malloc(sizeof(list_t)); //容错 if(list == NULL) { printf("空间申请失败!\n"); return NULL; } //初始化标志位,设置表为空(malloc出来的地方 数值可能是垃圾) list->last = -1; //返回堆区申请的空间首地址 return list;}
尾部增加:
int insert_tail_list(list_t* list,int data) { //0 容错 if(list==NULL||list->last==N-1) return -1;//不成功 (满了或者 表示NULL) //1 增加数据,赋值 list->data[list->last+1]=data; //2 修改last的值 list->last++; return 0;//成功}
头部增加:
int insert_head_list(list_t* list,int data) { //0 容错 if(list==NULL||list->last==N-1) return -1;//不成功 (满了或者 表示NULL) //1 挪,从最后一个数据元素开始挪,前一个数据给后一个数据 int i; for(i=list->last;i>=0;i--) { list->data[i+1]=list->data[i]; } //2 放数据 list->data[0]=data; //3 last++ list->last++; return 0;}
从指定位置增加:
int insert_index_list(list_t* list,int index,int data) { //0 容错 if(list==NULL||list->last==N-1||index<=-1||index>list->last+1) return -1; //1 挪,从最后一个数据元素开始挪,直到index的位置,将前一个给后一个 int i; for(i=list->last;i>=index;i--) { list->data[i+1]=list->data[i]; } //2 放数据 list->data[index]=data; //3 last++ list->last++; return 0;}
从头部删:
int delete_head_list(list_t* list) { //0 容错 if(list==NULL||list->last==-1) return -1; //1 挪 后一个数据给前一个数据 int i; for(i=0;i<list->last;i++) { list->data[i]=list->data[i+1]; } //2 last-- list->last--; return 0;}
从指定位置删:
//指定位置删除数据int delete_index_list(list_t * list, int index) { //0 容错 if(list==NULL||list->last==N-1||index<=-1||index>list->last+1) return -1; //1 挪(删除数据),从index开始挪,将后一个给前一个 int i; for(i=index; i<list->last;i++) { list->data[i]=list->data[i+1]; } //2 修改last的值 list->last--; return 0;}
查数据:
int locate_list(list_t* list,int data) { //有且只返回第一个找到的数据 //返回索引,0 ~N-1 //找不到返回-1 //0 容错 if(list==NULL||list->last==-1) return -1; //1 遍历查找 int i; for(i=0;i<=list->last;i++) { if(list->data[i]==data) return i; } return -1;}
改数据:
int change_index_list(list_t* list,int index,int data){ //0 容错 if(list==NULL||list->last==-1||index<=-1||index>list->last) return -1; //1 改数据 list->data[index]=data; //2 return 0;}
打印(遍历):
int print_list(list_t* list) { if(list==NULL||list->last==-1) return -1; //打印数据,从头打印,即为从0位置打印到最后有效位置间的有效数据元素 int i; for(i=0;i<=list->last;i++) { printf("%3d ",list->data[i]); } printf("\n"); return 0;}
清空:
int clear_list(list_t* list){ if(list==NULL) return -1; list->last=-1; return 0;}
销毁(free):
int destroy_list(list_t** list) { //需要使用二级指针 if(list==NULL||*list==NULL) return -1; free(*list); *list=NULL; return 0;}注意!!int destroy_list2(list_t* list) // 销毁不干净!!!!{ if(list==NULL) return -1; free(list); list = NULL; return 0;}
总代码:
#include #include #define SIZE 20typedef struct list{ int data[SIZE];//存放数据元素 int last;//标记位,标记表中最后一位有效数据的位置(记录数组下标)}list_t;//顺序表的类型//声明 list_t* create_list(void);int insert_tail_list(list_t* list,int data);int insert_head_list(list_t* list,int data);int insert_index_list(list_t* list,int index,int data);int delete_head_list(list_t* list);int locate_list(list_t* list,int data);int change_index_list(list_t* list,int index,int data);int print_list(list_t* list);int clear_list(list_t* list);int destroy_list(list_t** list);int destroy_list2(list_t* list);int main(int argc, const char *argv[]) { list_t* list = create_list(); int i; for(i=1;i<=18;i++) { //insert_tail_list(list,i*10); insert_head_list(list,i*10); print_list(list); } if(change_index_list(list,locate_list(list,150),666)==0) { printf("after change!\n"); print_list(list); } if(insert_index_list(list,locate_list(list,666),888)==0) { printf("after insert index\n"); print_list(list); } destroy_list(&list); //destroy_list2(list); if(list==NULL) { printf("list is safe cleard!\n"); } else { printf("list:%p\n", list); }#if 0 for(i=1;i<=20;i++) { delete_head_list(list); print_list(list); }#endif return 0;}//......//节约篇幅,不再赘述
第二代
在第一代中data[SIZE] 具有一定局限性,数据大小限制。采用第二代,Data独立开辟空间,新增一个大小标志位。
注意:指针是变量,数组名是常量。
定义结构体:
typedef struct list{ int *data;//需要在malloc的时候,再去给data分配空间 int size;//标记数据元素的个数 int last;//表示最后一个有效元素在数组的位置 // -1恰好比较合适表示 空}list_t;//顺序表的类型
初始化:
list_t* create_list(int size) { if(size<=0||size>=20000) return NULL;// NULL == (void *)0 //堆区申请空间,申请的顺序表的标识 list_t* list=malloc(sizeof(list_t)); if(list == NULL) { printf("空间申请失败!\n"); return NULL; } list->last=-1;//设置表为空(malloc出来的地方 数值可能是垃圾) //数据元素个数的初始化 list->size=size; //堆区申请存放数据元素的空间 list->data=malloc(sizeof(int)*size); //返回堆区申请的空间首地址 return list;}
尾部增加:
int insert_tail_list(list_t* list,int data){ //0 容错 if(list==NULL||list->last==list->size-1) return -1;//不成功 (满了或者 表示NULL) //1 list->data[list->last+1]=data; //2 list->last++; return 0;//成功}
头部增加:
int insert_head_list(list_t* list,int data) { //0 容错 if(list==NULL||list->last==N-1) return -1;//不成功 (满了或者 表示NULL) //1 挪,从最后一个数据元素开始挪,前一个数据给后一个数据 int i; for(i=list->last;i>=0;i--) { list->data[i+1]=list->data[i]; } //2 放数据 list->data[0]=data; //3 last++ list->last++; return 0;}
指定位置增加:
int insert_index_list(list_t* list,int index,int data) { //0 if(list==NULL||list->last==list->size-1||index<=-1||index>list->last+1) return -1; //1 挪 int i; for(i=list->last;i>=index;i--) { list->data[i+1]=list->data[i]; } //2 放数据 list->data[index]=data; //3 last++ list->last++; return 0;}
从头部删:
int delete_head_list(list_t* list) { if(list==NULL||list->last==-1) return -1; //1 int i; for(i=0;i<list->last;i++) { list->data[i]=list->data[i+1]; } list->last--; return 0;}
从指定位置删:
int delete_index_list(list_t * list, int index) { //0 容错 if(list==NULL||list->last==N-1||index<=-1||index>list->last+1) return -1; //1 挪(删除数据),从index开始挪,将后一个给前一个 int i; for(i=index; i<list->last;i++) { list->data[i]=list->data[i+1]; } //2 修改last的值 list->last--; return 0;}
查数据:
int locate_list(list_t* list,int data) { //有且只返回第一个找到的数据 //返回索引,0 ~N-1 //找不到返回-1 if(list==NULL||list->last==-1) return -1; int i; for(i=0;i<=list->last;i++) { if(list->data[i]==data) return i; } return -1;}
改数据:
int change_index_list(list_t* list,int index,int data) { //0 if(list==NULL||list->last==-1||index<=-1||index>list->last) return -1; //1 list->data[index]=data; //2 return 0;}
打印(遍历):
int print_list(list_t* list){ if(list==NULL||list->last==-1) return -1; int i; for(i=0;i<=list->last;i++) { printf("%3d ",list->data[i]); } printf("\n"); return 0;}
清空:
int clear_list(list_t* list){ if(list==NULL) return -1; list->last=-1; return 0;}
销毁:
int destroy_list(list_t** list){ if(list==NULL||*list==NULL) return -1; free((*list)->data); free(*list); *list=NULL; return 0;}
总代码:
#include #include typedef struct node{ int *data;//需要在malloc的时候,再去给data分配空间 int size; int last; //表示最后一个有效元素在数组的位置}list_t; //自定义类型申明//声明 list_t* create_list(int size);int insert_tail_list(list_t* list,int data);int insert_head_list(list_t* list,int data);int insert_index_list(list_t* list,int index,int data);int delete_head_list(list_t* list);int locate_list(list_t* list,int data);int change_index_list(list_t* list,int index,int data);int print_list(list_t* list);int clear_list(list_t* list);int destroy_list(list_t** list);int main(int argc, const char *argv[]) { list_t* list = create_list(50); int i; for(i=1;i<=18;i++) { //insert_tail_list(list,i*10); insert_head_list(list,i*10); print_list(list); } if(change_index_list(list,locate_list(list,150),666)==0) { printf("after change!\n"); print_list(list); } if(insert_index_list(list,locate_list(list,666),888)==0) { printf("after insert index\n"); print_list(list); } destroy_list(&list); //destroy_list2(list); if(list==NULL) { printf("list is safe cleard!\n"); } else { printf("list:%p\n", list); }#if 0 for(i=1;i<=20;i++) { delete_head_list(list); print_list(list); }#endif return 0;}//......//节约篇幅,不再赘述
第三代
利用零元数组。data[0] 不占大小!
定义结构体:
typedef struct node{ int size; int last; //表示最后一个有效元素在数组的位置 // -1恰好比较合适表示 空 int data[0]; //注意: 零元数组申明时,需要放在 结构体的尾部, //方便空间,data不占大小,但是实际存在}list_t //顺序表的类型
不再一一列举:增删改查如下:
#include #include typedef struct node{ int size; int last; //表示最后一个有效元素在数组的位置 int data[0]; //不占空间}list_t; //自定义类型申明//创建list_t* create_list(int size) { if(size<=0||size>=20000) return NULL;// NULL == (void *)0 list_t* list=malloc(sizeof(list_t)+sizeof(int)*size); list->last=-1;//设置表为空(malloc出来的地方 数值可能是垃圾) list->size=size; return list;}//增(尾部增加)int insert_tail_list(list_t* list,int data) { //0 容错 if(list==NULL||list->last==list->size-1) return -1;//不成功 (满了或者 表示NULL) //1 list->data[list->last+1]=data; //2 list->last++; return 0;//成功}//增 (头部)int insert_head_list(list_t* list,int data) { //0 容错 if(list==NULL||list->last==list->size-1) return -1;//不成功 (满了或者 表示NULL) //1 挪 int i; for(i=list->last;i>=0;i--) { list->data[i+1]=list->data[i]; } //2 放数据 list->data[0]=data; //3 last++ list->last++; return 0;}//增 (任意位置)int insert_index_list(list_t* list,int index,int data) { //0 if(list==NULL||list->last==list->size-1||index<=-1||index>list->last+1) return -1; //1 挪 int i; for(i=list->last;i>=index;i--) { list->data[i+1]=list->data[i]; } //2 放数据 list->data[index]=data; //3 last++ list->last++; return 0;}//删int delete_head_list(list_t* list) { if(list==NULL||list->last==-1) return -1; //1 int i; for(i=0;i<list->last;i++) { list->data[i]=list->data[i+1]; } list->last--; return 0;}//查int locate_list(list_t* list,int data) { if(list==NULL||list->last==-1) return -1; int i; for(i=0;i<=list->last;i++) { if(list->data[i]==data) return i; } return -1;}//改int change_index_list(list_t* list,int index,int data) { //0 if(list==NULL||list->last==-1||index<=-1||index>list->last) return -1; //1 list->data[index]=data; //2 return 0;}// 遍历int print_list(list_t* list) { if(list==NULL||list->last==-1) return -1; int i; for(i=0;i<=list->last;i++) { printf("%3d ",list->data[i]); } printf("\n"); return 0;}//清空 last =-1;int clear_list(list_t* list) { if(list==NULL) return -1; list->last=-1; return 0;}//销毁 free list list = NULL;int destroy_list(list_t** list) { if(list==NULL||*list==NULL) return -1; free(*list); *list=NULL; return 0;}int main(int argc, const char *argv[]) { list_t* list=create_list(50); int i; for(i=1;i<=18;i++) { //insert_tail_list(list,i*10); insert_head_list(list,i*10); print_list(list); } if(change_index_list(list,locate_list(list,150),666)==0) { printf("after change!\n"); print_list(list); } if(insert_index_list(list,locate_list(list,666),888)==0) { printf("after insert index\n"); print_list(list); } destroy_list(&list); if(list==NULL) { printf("list is safe cleard!\n"); }#if 0 for(i=1;i<=20;i++) { delete_head_list(list); print_list(list); }#endif return 0;}