线性表定义
线性表(List)是零个或多个数据元素的集合
线性表中的数据元素之间是有顺序的
线性表中的数据元素个数是有限的
线性表中的数据元素的类型必须相同
数学定义
线性表是具有相同类型的 n(≥ 0)个数据元素的有限序列
(a1, a2, …, an)
ai是表项,n 是表长度。
性质
a0为线性表的第一个元素,只有一个后继
an为线性表的最后一个元素,只有一个前驱
除a0和an外的其它元素ai,既有前驱,又有后继
线性表能够逐项访问和顺序存取
线性表的操作
创建线性表
销毁线性表
清空线性表
将元素插入线性表
将元素从线性表中删除
获取线性表中某个位置的元素
获取线性表的长度
线性表在程序中表现为一种特殊的数据类型
线性表的操作在程序中的表现为一组函数
线性表的顺序存储结构
1.基本概念
这指的是用一段地址连续的存储单元依次存储线性表的数据元素。2.设计与实现
(1)插入元素算法:
->判断线性表是否合法
->判断插入位置是否合法
->把最后一个元素到插入位置的元素后移一个位置
->将新元素插入
->线性表长度加1
(2)获取元素操作
->判断线性表是否合法
->判断位置是否合法
->直接通过数组下标的方式获取元素
(3)
删除元素算法
->判断线性表是否合法
->判断删除位置是否合法
->将元素取出
->将删除位置后的元素分别向前移动一个位置
->线性表长度减1
3.优点与缺点
优点:
无需为线性表中的逻辑关系增加额外的空间
可以快速的获取表中合法位置的元素
缺点:
插入和删除操作需要移动大量元素
当线性表长度变化较大时难以确定存储空间的容量
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");
}