顺序表
顺序表的小结
(1)利用数据元素的存储位置表示线性表中相邻数据元素之间的前后关系,即线性表的逻辑结构与存储结构一致。(以物理位置相邻表示逻辑关系)
顺序表的基本操作
1、插入
2、删除
3、查找
时间复杂度均为O(n),空间复杂度均为O(1).
顺序表的优缺点
优点
存储密度大(节点本身所占用的存储量/节点结构所占用的存储量)=1
可以随机存取表中任一元素
缺点
- 在插入、删除某一个元素时,需要移动大量的元素
- 浪费存储空间
- 属于静态存储形式(数组存储),数据元素的个数不能自由扩充。
线性表的链式存储结构
存储某个元素的同时,还存储了其下一个元素地址。
头指针H:记录第一个元素的地址
单链表是由头指针唯一确定,因此单链表可以用头指针的名字来命名。
NULL==0
各个节点由两个域组成:
数据域:存储元素数值数据。
指针域:存储直接后继节点的存储位置。
数据 指针
- 节点:数据元素的存储映像。由数据域和指针域两部分组成。
数据域 指针 - 链表:n个节点由指针链组成一个链表。
他是线性表的链式存储映像,称为线性表的链式存储结构
单链表:节点只有一个指针域的链表,称为单链表或线性链表。
L->| | |->|a1| |->|a2| |->|a3| |->...|an| ^
双链表:节点有两个指针域的链表。(一个数据域两个指针域的链表)
一个用来存储后继元素的地址(指向后继元素)
另一个指针域存储其前驱元素的地址
循环链表:首尾相接的链表称为循环链表(最后一个元素an的指针域存储头节点(首源节点)的地址)
头指针、头节点和首元节点
头指针 头节点 首元结点
- 头指针:是指向链表中第一个节点的指针。
- 头节点:(往往不是存储第一个元素,额外附加的节点)(整个链表的头):是在链表的首元节点之前附设的一个节点;
- 首元节点:是指链表中存储第一个数据元素a1的节点
链表的存储结构示意图两种形式
1、不带头节点
2、带头节点
如何表示空表(没有数据元素,表长为零)
1、不带头节点: 头指针为空
head |^| 空表
2、带头节点:头节点的指针域为空时表示空表
head ->| |^|空表
设置头节点的好处
1、便于首元节点的处理
2、便于空表和非空表的统一处理
头节点数据域内的内容:可以为空,也可以存放线性表长度等附加信息,但此节点不能计入链表长度值
链表的特点:
1、存储位置是任意的
2、访问只能通过头指针进入链表,并通过每个节点的指针域依次向后顺序扫描其余节点,寻找第一个节点和最后一个节点花费的时间不相等。(这种存取方式称为顺序存取法)
顺序表:随机存取(O(1))
链表:顺序存取
单链表(带头结点)
数据域 指针域---->data next
typedef struct Lnode{//typedef重新定义了一个类型
ElemType data;//节点的数据域
struct Lnode*next;//节点的指针域(指向struct Lnode类型的指针)
}Lnode,*LinkList;//LinkList为指向结构体Lnode的指针类型
eg:
存储学生学号,姓名,成绩单链表节点类型定义如下:
typedef Struct student{
char num[8];
char name[8];
int score;//数据域
struct student*next;//指针域(指针指向Struct student类型的变量(嵌套))
}Lnode,*LinkList;
定义一个链表
LinkList L;
为了统一链表,通常定义成一个结构类型
typedef Struct {
char num[8];
char name[8];
int score;//数据域
}ElemType;
typedef Struct Lnode{
ElemType data;//数据域
struct student*next;//指针域
}Lnode,*LinkList;