线性表(List)是零个或多个数据元素的集合
线性表中的数据元素之间是有顺序的
线性表中的数据元素个数是有限的
线性表中的数据元素的类型必须相同
线性表是具有相同类型的 n(≥ 0)个数据元素的有限序列
(a1, a2, …, an)
ai是表项,n 是表长度。
a0为线性表的第一个元素,只有一个后继
an为线性表的最后一个元素,只有一个前驱
除a0和an外的其它元素ai,既有前驱,又有后继
线性表能够逐项访问和顺序存取
创建线性表
销毁线性表
清空线性表
将元素插入线性表
将元素从线性表中删除
获取线性表中某个位置的元素
获取线性表的长度
线性表在程序中表现为一种特殊的数据类型
线性表的操作在程序中的表现为一组函数
(1)插入元素算法:
->判断线性表是否合法
->判断插入位置是否合法
->把最后一个元素到插入位置的元素后移一个位置
->将新元素插入
->线性表长度加1
(2)获取元素操作
->判断线性表是否合法
->判断位置是否合法
->直接通过数组下标的方式获取元素
->判断线性表是否合法
->判断删除位置是否合法
->将元素取出
->将删除位置后的元素分别向前移动一个位置
->线性表长度减1
优点:
无需为线性表中的逻辑关系增加额外的空间
可以快速的获取表中合法位置的元素
缺点:
插入和删除操作需要移动大量元素
当线性表长度变化较大时难以确定存储空间的容量
seqlist.h #ifndef _WBM_LIST_H_ #define _WBM_LIST_H_ typedef void List; typedef void ListNode; //创建并且返回一个空的线性表 List* LinkList_Create(); //销毁一个线性表list void List_Destroy(List* list); //将一个线性表list中的所有元素清空, 线性表回到创建时的初始状态 void List_Clear(List* list); //返回一个线性表list中的所有元素个数 int List_Length(List* list); //向一个线性表list的pos位置处插入新元素node int List_Insert(List* list, ListNode* node, int pos); //获取一个线性表list的pos位置处的元素 ListNode* List_Get(List* list, int pos); //删除一个线性表list的pos位置处的元素 返回值为被删除的元素,NULL表示删除失败 ListNode* List_Delete(List* list, int pos); #endif
seqlist.c #include "stdlib.h" #include "stdio.h" #include "string.h" #include "seqlist.h" typedef struct _tag_SeqList { int capacity; int length; unsigned int *node ; // unsigned int nodeAarry[100] //void *node ; }TSeqList; //typdef的意思 把void 重新命名成SeqList /* void * SeqList_Create2(int capacity) { TSeqList *ret = NULL; ret = (TSeqList *)malloc(sizeof(TSeqList)); if (ret == NULL) { return NULL; } ret->capacity = capacity; ret->node = (unsigned int *)malloc(sizeof(unsigned int ) * capacity); if (ret->node == NULL) { return NULL; } ret->length = 0; return ret; } */ void * SeqList_Create(int capacity) { TSeqList *ret = NULL; if (capacity <= 0) { return NULL; } ret = (TSeqList *)malloc(sizeof(TSeqList) + sizeof(unsigned int ) * capacity ); if (ret == NULL) { return NULL; } ret->capacity = capacity; ret->node = (unsigned int *)(ret + 1); ret->length = 0; return ret; } void SeqList_Destroy(SeqList* list) { if (list == NULL) { return ; } free(list); return ; } void SeqList_Clear(SeqList* list) { TSeqList *tlist = NULL; if (list == NULL) { return ; } tlist = (TSeqList *)list; tlist->length = 0; return ; } int SeqList_Length(SeqList* list) { TSeqList *tlist = list; if (list == NULL) { return -1; } return tlist->length; } int SeqList_Capacity(SeqList* list) { TSeqList *tlist = list; if (list == NULL) { return -1; } return tlist->capacity; } int SeqList_Insert(SeqList* list, SeqListNode* node, int pos) { int i = 0; TSeqList *tlist = list; if (list == NULL || node== NULL ) { return -1; } if (pos<0 || pos>=tlist->capacity ) { return -2; } //判断是否已经man if (tlist->length >= tlist->capacity) { return -3; } //容错 if (pos > tlist->length) { pos = tlist->length; } //插入算法 有两步 //从插入的位置 后移元素 //注意length能表示出现在数组的最后元素位置 //最后元素的下标为 tlist->node[length-1]; for (i=tlist->length; i>pos; i--) { tlist->node[i] = tlist->node[i-1]; } //在pos位置插入元素 tlist->node[pos] = (unsigned int)node; //20140514这个地方不能加 (unsigned int *) //如果你加*,说明你对 unsigned int *node ; // unsigned int nodeAarry[100]还没有理解 tlist->length ++; return 0; } SeqListNode* SeqList_Get(SeqList* list, int pos) { int i = 0; TSeqList *tlist = list; //if (list== NULL || pos<0 || pos>=tlist->length) if (list== NULL || pos<0 || pos>tlist->length) { return NULL; } return (SeqListNode*)tlist->node[pos]; } SeqListNode* SeqList_Delete(SeqList* list, int pos) { int i = 0; TSeqList *tlist = list; SeqListNode* ret = NULL; if (list == NULL || pos<0 || pos>tlist->length) { return NULL; } //缓存要删除的结点 ret = (SeqListNode*)tlist->node[pos]; //对链表进行移动 for (i=pos+1; i<tlist->length; i++) { tlist->node[i-1] = tlist->node[i]; } tlist->length --; return ret; }
#include "stdlib.h" #include "stdio.h" #include "string.h" #include "seqlist.h" typedef struct _Teacher { char name[64]; int age ; int buf; }Teacher; void main() { int ret = 0, i = 0; Teacher t1, t2, t3; SeqList* list = NULL; t1.age = 10; t2.age = 20; t3.age = 30; list = SeqList_Create(10); //仔细思考:业务数据 和 链表算法(底层库)是如何分离的。。。。。。 //业务数据结点的管理(内存的生命周期)甩给了上层应用(业务模型) ret = SeqList_Insert(list, (SeqListNode*) &t1, 0); ret = SeqList_Insert(list, (SeqListNode*) &t2, 0); ret = SeqList_Insert(list, (SeqListNode*) &t3, 0); //循环遍历 for (i=0; i<SeqList_Length(list); i++) { Teacher *tmp = (Teacher *)SeqList_Get(list, i); printf("age:%d \n", tmp->age); } //循环删除 for (i=0; i<SeqList_Length(list); i++) { SeqList_Delete(list, 0); } SeqList_Destroy(list); system("pause"); }