3表结构的基本概念
线性表
什么是线性表?
线性表(linear list):具有n(n≥0)个数据结点(元素)的序列 A=(a1,a2,…,an)。比如:数组
表结构的主要运算:增、删、改、查。
其次还有:存取、更新、合并、分裂、复制、排序
线性表有两个存储方式:顺序存储(顺序表)、链式存储(链表)
顺序表
按结点在表中的次序依次存储
特点:结点的逻辑次序与物理次序一致。
结点i的存储地址公式:
Loc(i)=(i-1)*t+c (i=1,2,3……n)
c:首地址
t:结点长度(占内存单元数)
换句话说:
用数组存储
数组的一个元素便是一个存储结点
下标作为结点的存储地址(相对地址)
单向链表
链表是由一个个结点,通过连接组成,每一个结点都有数据域和指针域。
值域(数据域) :存储表元素值
链域(指针域):存储后继结点的存储地址
注意:
1.第一个结点:头结点
2.最后一个结点:尾结点
3.某结点称它的前一个结点:前驱
4.某结点称它的后一个结点:后继
4.链表除头、尾结点外,其他结点有且只有一个前驱和一个后继。
如图:
顺序表的封装:
定义list类型:
typedef struct //定义表的存储结构类型
{ char list_name[name_length]; //表名称
int length ; //表长度
element_type d[N]; //存储表元素的数组
} list
用list类型定义表变量team
list team;
链表的封装:
定义link_list类型:
typedef struct
{ char list_name[name_length];//表名称域
int length; //表长度域
ptr head; //表头指针域
} link_list; //链表类型名
两者的区别:
优点:
1.顺序表可以以下标方式进行访问,对指定的某一个值进行修改和查询。
2.顺序表的地址是连续的,可以通过地址查找下、下一个值。
3.链表对数值的插入、删除比较方便、只需改变该结点的前驱和后继。
4.链表是动态分配内存,可以无限地进行存储,并且使用完后可以立即释放、给下一个数据使用。
缺点:
1.顺序表的空间是固定的,初始化时要分配好内存,不可以越界。
2.顺序表的增、删比较麻烦,该在中间增加一个数值,而其后的全部元素都有依次往外移动一位。
3.顺序表的元素被删除后,空间仍存在,只能一次性释放,不可以足个释放。空间利用率不高。
4.链表的查找麻烦。查找一个数值,要从头指针开始遍历,每一次都是如此。
5.链表容易数据流失,要找到某一个结点,必须得到该结点的前一结点的指针域。若第二结点丢失,那么后面的结点将找不到。(因为链表是动态分配内存,物理地址是不连续的)
因此,链表还有双向链表(可以同时得到结点的前驱和后继),循环链表(头、尾指针同一处,提高查找效率)