线性表的定义
- 线性表(list)是零个或者多个数据元素的集合
- 线性表中的数据元素之间是有顺序的
- 线性表中的数据元素个数是有限的
- 线性表中数据元素的类型必须相同
定义
线性表是具有相同类型的n(>=0)个数据元素的有限序列
(a1,a2, …,an)
ai是表项,n是表长度
性质
- a0为线性表的第一个元素,只有一个后继
- an为线性表的最后一个元素,只有一个前驱
- 除a0和an,外的其它元素ai;,既有前驱,又有后继
- 线性表能够逐项访问和顺序存取
线性表的操作
一些常用操作
typedef void List;
typedef void ListNode;
//创建线性表
List* list_Create();
//销毁线性表
void List_Destroy(List* list);
//清空线性表
void List_Clear(List* list);
//获取线性表的长度
int List_Length(List* list);
//元素插入线性表;在线性表list的pos位置插入新元素node
//返回值为1表示插入成功,0表示插入失败
int List_Insert(List* list,ListNode* node,int pos);
//获取线性表中某个位置的元素;获取线性表list的pos位置处的元素
//返回值为pos位置处的元素,NULL表示获取失败
ListNode* List_Get(List* list,int pos);
//将某个元素从线性表中删除;删除线性表list的pos位置处的元素
//返回值为删除的元素,NULL表示获取失败
ListNode* List_Delete(List* list,int pos);
小结
- 线性表在程序中表现为一种特殊的数据类型
- 线性表的操作表现为一组相关的函数
线性表的顺序存储结构
顺序存储定义
线性表的顺序存储结构;指的是用一段地址连续的存储单元依次存储线性表的数据元素
在C语言中可以用一维数组来实现顺序存储结构
#define MAXSIZE 20 //线性表的最大容量,存贮空间初始分配量
typedef int ElemType; //ElemType的类型根据实际情况而定,这里为int
typedef struct tag_List
{
ElemType data[MAXSIZE]; //数组data,存储数据元素
int length; //线性表当前长度
}list;
获取元素操作
- 判断线性表是否合法
- 判断位置是否合法
- 直接通过数组下标的方式获取元素
char GetElem(List* list,int pos)
{
char ret = -1;
//1.判断线性表是否合法
//2.判断位置是否合法
if((list!=NULL)&&(0<=pos)&&(pos<=list->length))
{
//3.获取元素
ret = list->data[pos];
}
return ret;
}
插入元素操作
- 判断线性表是否合法
- 判断插入位置是否合法
- 把最后一个元素到插入位置的元素都后移一位
- 将新元素插入
- 线性表长度加1
//!!!注意:pos指的是在数组中的位置,是线性表的位置i-1的结果
int List_Insert(List* list,char e,int pos)
{
//1,判断线性表是否合法
int ret = (list != NULL); //不为空则运行后续
int k = 0; //临时循环变量
//2,判断插入位置是否合法
ret = ret && ((list->length + 1) <= MAXSIZE);
ret = ret && (pos >= 0);
if(ret) //都通过了,则进入下一步
{
if( pos >= list->length)
{ //如果插入的位置大于线性表的实际长度,则插入在线性表末尾
pos = list->length
}
//3.从最后一个元素开始向前遍历到第pos个位置
// 分别将他们都向后移动一个位置
for(k=list->length;k>pos;k--)
{
list->data[k] = list->data[k-1];
}
//4.将新元素插入
list->data[k] = e;
//5.长度加1
list->length++;
}
return ret;
}
换一种写法
//i是新元素插入线性表1~n的位置
int List_Insert(List* list,char e,int i)
{
//1,判断线性表是否合法
int ret = (list != NULL);
int k; //临时循环变量
//2,判断插入位置是否合法
ret = ret && ((list->length + 1)<= MAXSIZE);
ret = ret $$ (i >= 1);
if(ret)
{
if(i > list->length)
{
i = list->length;
}
//3.从最后一个元素开始向前遍历到第i个位置
// 分别将他们都向后移动一个位置
for(k=list->length-1;k>=i-1;i--)
{
list->data[k+1] = list->data[k];
}
//4.将新元素插入
list->data[i-1] = e;
//5.长度加1
list->length++;
}
}
删除元素操作
- 判断线性表是否合法
- 判断删除位置是否合法
- 将元素取出
- 将删除位置后的元素分别向前移动一个位置
- 线性表长度减1
char List_Delete(List* list,int pos)
{
char ret = -1;
int i = 0; //临时循环
//1.判断线性表是否合法
//2.判断删除位置是否合法
if((list != NULL)&&(0<=pos)&&(pos< list->length))
{
//3.取出删除元素
ret = list->data[pos];
//4.把删除位置pos后的元素分别向前移动一个位置
for(i = pos+1;i<list->length;i++)
{
list->data[i-1] = list->data[i];
}
//5.长度加1
list->length--;
}
return ret;
}
**创建可复用顺序线性表
代码写在这个连接
优点
- 无需为线性表中的逻辑关系增加额外的空间
- 可以快速的获取表中合法位置的元素
缺点
- 插入和删除操作需要移动大量的元素
- 当线性表长度变化较大时难以确定储存空间